package com.jinke.api.modules.app.service.impl;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
import com.jinke.api.common.api.CommonPage;
import com.jinke.api.common.api.CommonResult;
import com.jinke.api.common.exception.Asserts;
import com.jinke.api.common.util.*;
import com.jinke.api.modules.api.conf.ApiUrlsConfig;
import com.jinke.api.modules.app.config.ExcelBilledListener;
import com.jinke.api.modules.app.config.ExcelOrderListener;
import com.jinke.api.modules.app.controller.StaticController;
import com.jinke.api.modules.app.controller.param.CompanySellerProfitParam;
import com.jinke.api.modules.app.enums.ChannelPlatform;
import com.jinke.api.modules.app.enums.*;
import com.jinke.api.modules.app.mapper.OrderMapper;
import com.jinke.api.modules.app.model.*;
import com.jinke.api.modules.app.request.*;
import com.jinke.api.modules.app.response.*;
import com.jinke.api.modules.app.service.*;
import com.jinke.api.modules.app.util.EasyExcel;
import com.jinke.api.modules.app.util.MathUtil;
import com.jinke.api.modules.app.util.ParcelUtil;
import com.jinke.api.modules.app.util.OssUtil;
import com.jinke.api.modules.base.constant.Constants;
import com.jinke.api.modules.base.service.BaseShipService;
import com.jinke.api.modules.base.service.ShipFactory;
import com.jinke.api.modules.third.ezeeship.model.request.EstimateRateRequest;
import com.jinke.api.modules.third.ezeeship.model.response.EstimateRateResponse;
import com.jinke.api.modules.third.trackApi.TrackApiUtils;
import com.jinke.api.modules.third.uniuni.model.dto.UniPrintLabelReqDTO;
import com.jinke.api.modules.third.uniuni.model.response.UniPrintLabel;
import com.jinke.api.modules.third.uniuni.model.response.UniPrintPdtResponse;
import com.jinke.api.modules.third.uniuni.tool.UniUniRequest;
import com.jinke.api.modules.ums.dto.*;
import com.jinke.api.modules.ums.model.*;
import com.jinke.api.modules.ums.request.UNRefundedOrderPageRequest;
import com.jinke.api.modules.ums.request.UserReleaseEarnestRequest;
import com.jinke.api.modules.ums.service.*;
import com.jinke.api.modules.ums.vo.BilledDetailVo;
import com.jinke.api.modules.ums.vo.SimpleUser;
import com.jinke.api.modules.ums.vo.UNRefundedOrderPageVO;
import com.jinke.api.modules.ums.vo.UserChannelVO;
import com.jinke.api.modules.user.model.UserOrderInter;
import com.jinke.api.modules.user.service.UmsAdminPriceRuleRelationService;
import com.jinke.api.modules.user.service.UserOrderInterService;
import com.jinke.api.security.util.AdminUserUtil;
import com.jinke.api.security.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * <p>
 * 承运商平台 服务实现类
 * </p>
 *
 * @author macro
 * @since 2024-01-15
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Autowired
    private OrderParcelService orderParcelService;
    @Autowired
    private ShipFactory shipFactory;
    @Autowired
    private ChannelService channelService;
    @Autowired
    private ChannelCarrierService channelCarrierService;
    @Autowired
    private UmsAdminService adminService;
    @Autowired
    private SysMessageService sysMessageService;
    @Resource
    private UmsAdminService umsAdminService;
    @Autowired
    private IOrderTaskService iOrderTaskService;
    @Resource
    private OrderService orderService;
    @Resource
    private UmsAdminPriceRuleRelationService umsAdminPriceRuleRelationService;
    @Resource
    private PriceRuleService priceRuleService;
    @Resource
    private PriceSurchargeService priceSurchargeService;
    @Resource
    private UserOrderInterService userOrderInterService;

    @Resource
    private RestTemplate restTemplate;
    @Resource
    private OssUtil ossUtil;
    @Resource
    private ApiUrlsConfig apiUrlsConfig;

    @Resource
    private StaticController staticController;
    @Resource
    private Executor ezeeShipThreadPool;
    @Resource
    private UserChannelService userChannelService;
    @Resource
    private BalanceLogService balanceLogService;
    @Resource
    private OrderMapper orderMapper;

    @Resource
    private UmsAdminRoleRelationService adminRoleRelationService;

    @Resource
    private FedexRateTool fedexRateTool;

    @Resource
    private UniUniRequest uniUniRequest;
    @Resource
    private UserRechargeService userRechargeService;


    @Override
    public List<GetOrdersResponse> buildOrders(List<ExcelOrder> list) {
        List<GetOrdersResponse> orders = new ArrayList<>();
        int x = 1;
        try {

            for (int i = 0; i < list.size(); i++) {
                x++;
                ExcelOrder excelOrder = list.get(i);


                // 不满足抛异常
                Asserts.isTrue(StrUtil.isNotBlank(excelOrder.getSender()), "sender can not be empty");

                // 这个是包裹
                OrderParcel orderParcel = new OrderParcel();
                orderParcel.setHeight(excelOrder.getDimensionsH().toString());
                orderParcel.setLength(excelOrder.getDimensionsL().toString());
                orderParcel.setWidth(excelOrder.getDimensionsW().toString());


                BigDecimal weightLbKg = excelOrder.getWeightLbKg();
                if (weightLbKg == null) {
                    weightLbKg = BigDecimal.ZERO;
                }
                orderParcel.setWeight(weightLbKg.toString());

                BigDecimal orderWeightOzG = excelOrder.getWeightOzG();
                if (orderWeightOzG == null) {
                    orderWeightOzG = BigDecimal.ZERO;
                }
                orderParcel.setWeight(weightLbKg.toString());
                orderParcel.setWeight2(orderWeightOzG.toString());
                orderParcel.setPackageCode("your_package");
                Integer packageNumber = excelOrder.getPackageNumber();
                orderParcel.setPackageNum(packageNumber);
                String unit = excelOrder.getUnit();
                String[] units = unit.split("/");
                orderParcel.setMassUnit(units[0]);
                if (units.length > 1) {
                    String distanceUnit = units[1];
                    if ("inch".equals(distanceUnit.toLowerCase())) {
                        distanceUnit = "in";
                    }
                    orderParcel.setDistanceUnit(distanceUnit);
                }
//            for (int j = 1; j < packageNumber; j++) {
//                OrderParcel newOrderPardel = new OrderParcel();
//                BeanUtils.copyProperties(orderParcel, newOrderPardel);
//                orderParcels.add(newOrderPardel);
//            }

                if (excelOrder.getOrderCount() == null) {
                    List<OrderParcel> preParcels = orders.get(orders.size() - 1).getParcels();
                    preParcels.add(orderParcel);
                    // 把包裹放到上一个信息去
                    continue;
                }
                GetOrdersResponse order = new GetOrdersResponse();
                BeanUtils.copyProperties(excelOrder, order);
                order.setOrderNo(excelOrder.getOrderNo());
                if (StringUtils.isBlank(order.getOrderNo())) {
                    UUID uuid4 = UUID.randomUUID();
                /*String suffix = uuid4.toString().replaceAll("-", "");
                order.setOrderNo("202401A0000" + orderNo.substring(orderNo.length() - 4));*/
                    String prefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
                    String suffix = uuid4.toString().replaceAll("-", "");
                    order.setOrderNo(prefix + suffix.substring(suffix.length() - 4));
                }
                order.setFromCity(excelOrder.getSenderCity());
                order.setFromEmail(excelOrder.getSenderEmail());
                order.setFromCompany(excelOrder.getSenderCompany());
                order.setFromPhone(excelOrder.getSenderTelephone());
                order.setFromAddressLine2(excelOrder.getSenderAddress2());
                order.setFromAddressLine1(excelOrder.getSenderAddress1());
                order.setFromCountryCode(excelOrder.getSenderCountry());
                order.setFromZipCode(excelOrder.getSenderZipcode());
                order.setFromPersonName(excelOrder.getSender());
                order.setFromStateCode(excelOrder.getSenderState());

                order.setToCity(excelOrder.getRecipientCity());
                order.setToEmail(excelOrder.getRecipientEmail());
                order.setToCompany(excelOrder.getRecipientCompany());
                order.setToPhone(excelOrder.getRecipientTelephone());
                order.setToAddressLine2(excelOrder.getRecipientAddress2());
                order.setToAddressLine1(excelOrder.getRecipientAddress1());
                order.setToCountryCode(excelOrder.getRecipientCountry());
                order.setToZipCode(excelOrder.getRecipientZipcode());
                order.setToPersonName(excelOrder.getRecipient());
                order.setToStateCode(excelOrder.getRecipientState());
                order.setOrderType(OrderType.BATCH);

                boolean b = Arrays.stream(BatteryTypeEnums.values()).noneMatch(batteryType -> batteryType.getValue().equals(Optional.ofNullable(excelOrder.getBatteryType()).orElse(1)));
                Asserts.isTrue(!b, "batteryType is wrong");
                order.setBatteryType(excelOrder.getBatteryType());

                List<OrderParcel> orderParcels = new ArrayList<>();
                orderParcels.add(orderParcel);
                order.setParcels(orderParcels);
                orders.add(order);
            }
        } catch (Exception e) {
            log.error(e.getMessage()+"daoru");
            String message = "第" + x + "行数据异常";
            Asserts.fail(message);
        }
        return orders;
    }

    public List<ExcelOrderExport> buildAdminExOrderExports(List<GetOrdersResponse> ordersResponses,Map<Integer, UmsAdmin> sellerMap,
                                                           Map<Integer, List<OrderParcel>> orderParcelMap) {
        if (CollectionUtil.isEmpty(ordersResponses)) {
            return new ArrayList<>();
        }

        List<Order> orders = ordersResponses.stream().map(x -> {
            Order order = new Order();
            BeanUtils.copyProperties(x, order);
            return order;
        }).collect(Collectors.toList());


//        List<Integer> orderIds = orders.stream().map(Order::getId).collect(Collectors.toList());
        Set<Integer> channelIds = orders.stream().map(Order::getChannelId).collect(Collectors.toSet());
        List<Channel> channels = channelService.list(new LambdaQueryWrapper<Channel>().in(Channel::getId, channelIds));
        Map<Integer, Channel> channelMap = channels.stream()
                .collect(Collectors.toMap(Channel::getId, Function.identity()));

        Map<Integer, String> channelCarrierMap = new HashMap<>();

        if (CollectionUtil.isNotEmpty(channels)) {
            Set<Integer> channelCarrierIds = channels.stream().map(Channel::getChannelCarrierId).collect(Collectors.toSet());
            channelCarrierMap = channelCarrierService.list(new LambdaQueryWrapper<ChannelCarrier>()
                            .in(ChannelCarrier::getId, channelCarrierIds))
                    .stream().collect(Collectors.toMap(ChannelCarrier::getId, ChannelCarrier::getChannelCarrierName));

        }

//        Map<Integer, List<OrderParcel>> orderParcelMap = orderParcelService.list(new LambdaQueryWrapper<OrderParcel>().in(OrderParcel::getOrderId, orderIds))
//                .stream().collect(Collectors.groupingBy(OrderParcel::getOrderId));

        List<ExcelOrderExport> excelOrders = new ArrayList<>();
        for (int i = 0; i < orders.size(); i++) {

            Order order = orders.get(i);
            ExcelOrderExport excelOrder = new ExcelOrderExport();
            BeanUtils.copyProperties(order, excelOrder);

            excelOrder.setOrderNo(order.getOrderNo());
            DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime createTime = order.getCreateTime();
            if (createTime!=null){

                excelOrder.setLabelCreatTime(createTime.format(pattern));
            }

            Channel channel = channelMap.get(order.getChannelId());
            if (channel != null) {
                excelOrder.setServiceName(channel.getChannelName());
                excelOrder.setCarrierName(channelCarrierMap.get(channel.getChannelCarrierId()));
            }

            excelOrder.setEstimateCost(order.getRate());

            Integer orderId = order.getId();
            List<OrderParcel> tmpParcels = orderParcelMap.get(orderId);
            if (CollectionUtil.isNotEmpty(tmpParcels)) {
                Set<String> trackings = tmpParcels.stream().map(OrderParcel::getTrackingNumber).filter(Objects::nonNull).collect(Collectors.toSet());

                excelOrder.setTrackingID(CollectionUtil.join(trackings, ","));
            }

            UmsAdmin umsAdmin = sellerMap.get(order.getUserId());
            if (umsAdmin != null) {
                excelOrder.setUserEmail(umsAdmin.getEmail());
                if (StringUtils.isNotBlank(umsAdmin.getRealName())){

                    excelOrder.setRealName(umsAdmin.getRealName());
                }else {

                    excelOrder.setRealName(umsAdmin.getUsername());
                }
            }
            excelOrder.setReference(order.getReference());
            excelOrder.setReference2(order.getReference2());
            excelOrder.setStatus(OrderStatus.defaultEnum(order.getStatus()).toString());
            excelOrder.setSenderCity(order.getFromCity());
            excelOrder.setSenderEmail(order.getFromEmail());
            excelOrder.setSenderCompany(order.getFromCompany());
            excelOrder.setSenderPhone(order.getFromPhone());
            excelOrder.setSenderAddressLine1(order.getFromAddressLine1());
            excelOrder.setSenderAddressLine2(order.getFromAddressLine2());
            excelOrder.setSenderCountryCode(order.getFromCountryCode());
            excelOrder.setSenderZipCode(order.getFromZipCode());
            excelOrder.setSenderName(order.getFromPersonName());
            excelOrder.setSenderStateCode(order.getFromStateCode());

            excelOrder.setRecipientCity(order.getToCity());
            excelOrder.setRecipientEmail(order.getToEmail());
            excelOrder.setRecipientCompany(order.getToCompany());
            excelOrder.setRecipientPhone(order.getToPhone());
            excelOrder.setRecipientAddressLine1(order.getToAddressLine1());
            excelOrder.setRecipientAddressLine2(order.getToAddressLine2());
            excelOrder.setRecipientCountryCode(order.getToCountryCode());
            excelOrder.setRecipientZipCode(order.getToZipCode());
            excelOrder.setRecipientName(order.getToPersonName());
            excelOrder.setRecipientStateCode(order.getToStateCode());
            //保证金
            excelOrder.setEarnest(order.getEarnest());
            excelOrder.setCancelTime(order.getCancelTime());
            // api成本价 超级管理员要导出
            excelOrder.setOriginFee(order.getOriginFee());
            //销售
            if (order.getSellerId() != null) {

                UmsAdmin seller = sellerMap.get(order.getSellerId());
                if (seller!= null) {

                    excelOrder.setSeller(seller.getRealName());
                }
            }
            BigDecimal totalWeight = BigDecimal.ZERO;
            BigDecimal totalHeight = BigDecimal.ZERO;
            BigDecimal totalWidth = BigDecimal.ZERO;
            BigDecimal totalLength = BigDecimal.ZERO;
            if (CollectionUtil.isNotEmpty(tmpParcels)) {
                excelOrder.setMassUnit(tmpParcels.get(0).getMassUnit());
                excelOrder.setDistanceUnit(tmpParcels.get(0).getDistanceUnit());
                for (int j = 0; j < tmpParcels.size(); j++) {
                    OrderParcel orderParcel = tmpParcels.get(j);
                    BigDecimal weight = BigDecimal.valueOf(Double.valueOf(orderParcel.getWeight()));
                    totalWeight = totalWeight.add(weight);

                    BigDecimal height = new BigDecimal(orderParcel.getHeight());
                    totalHeight = totalHeight.add(height);

                    BigDecimal width = new BigDecimal(orderParcel.getWidth());
                    totalWidth = totalWidth.add(width);

                    BigDecimal length = new BigDecimal(orderParcel.getLength());
                    totalLength = totalLength.add(length);

                }
            }
            excelOrder.setTotalWeight(totalWeight);
            excelOrder.setTotalHeight(totalHeight);
            excelOrder.setTotalWidth(totalWidth);
            excelOrder.setTotalLength(totalLength);
            excelOrders.add(excelOrder);
        }

        return excelOrders;
    }

    /**
     * 查询运单
     * @param request
     * @return
     */
    @Override
    public CommonPage<GetOrdersResponse> getGetOrdersResponseCommonPage(OrderExportsRequest request) {
        Page<Order> page = new Page<>(request.getPageNum(), request.getPageSize());
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        Integer userId = request.getUserId();
        if (userId != null) { // 用户端传过来
            wrapper.eq(Order::getUserId, userId);
        } else {
            // 管理端
            UmsAdmin userInfo = AdminUserUtil.getUserInfo();
            if (userInfo.isSeller()) { // 如果是销售只能看自己或者自己相关的数据
                Integer sellerId = userInfo.getId();
                wrapper.and(wp -> {
                    wp.eq(Order::getUserId, sellerId)
                            .or().eq(Order::getSellerId, sellerId);
                });
            }
        }

        List<OrderStatus> status = request.getStatus();
        if (CollectionUtil.isNotEmpty(status)) {
//            if (OrderStatus.CANCEL2.equals(status)) {
//                wrapper.and(wp -> {
//                    wp.eq(Order::getStatus, OrderStatus.CANCEL_ING).or().eq(Order::getStatus, OrderStatus.CANCEL)
//                            .or().eq(Order::getStatus, OrderStatus.VOIDED);
//                });
//            }

            //else {
            //   wrapper.eq(Order::getStatus, status);
            // }
            wrapper.and(wp -> {
                for (OrderStatus st : status) {
                    wp.or(w -> {
                        w.eq(Order::getStatus, st.getValue());
                    });
                }
            });

        }

        List<String> requestOrderIds = request.getOrderIds();
        if (CollectionUtil.isNotEmpty(requestOrderIds)) {
            wrapper.in(Order::getId, requestOrderIds);
        }
        //渠道名称过滤条件
        wrapper.in(CollectionUtil.isNotEmpty(request.getChannelIds()), Order::getChannelId, request.getChannelIds());

        List<Integer> searchIds = new ArrayList<>();
        List<String> emails = request.getEmails();
        if (CollectionUtil.isNotEmpty(emails)) {
            LambdaQueryWrapper<UmsAdmin> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.and(wp -> {
                for (String email : emails) {
                    wp.or(w -> {
                        w.likeRight(UmsAdmin::getEmail, email);
                    });
                }
            });
            searchIds = umsAdminService.list(queryWrapper).stream().map(UmsAdmin::getId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(searchIds)) {
                searchIds = Arrays.asList(-1);
            }
        }
        wrapper.in(!searchIds.isEmpty(), Order::getUserId, searchIds);

        List<String> orderNos = request.getOrderNos();
        if (CollectionUtils.isNotEmpty(orderNos)) {
            // 创建一个外部条件，用于包含所有关键字的 OR 连接
            wrapper.and(wp -> {
                for (String keyword : orderNos) {
                    wp.or(w -> {
                        w.like(Order::getOrderNo, keyword);
                    });
                }
            });
        }

        List<String> platformNos = request.getPlatformNos();
        if (CollectionUtils.isNotEmpty(platformNos)) {
            // 创建一个外部条件，用于包含所有关键字的 OR 连接
            wrapper.and(wp -> {
                for (String keyword : platformNos) {
                    wp.or(w -> {
                        w.like(Order::getPlatformNo, keyword);
                    });
                }
            });
        }

        List<String> trackingNos = request.getTrackingNos();
        if (CollectionUtils.isNotEmpty(trackingNos)) {
            Set<Integer> orderParcelsOIds = new HashSet<>();
            orderParcelsOIds.add(-1);
            List<OrderParcel> orderParcels = orderParcelService.list(new LambdaQueryWrapper<OrderParcel>()
                    .in(OrderParcel::getTrackingNumber, trackingNos));
            if (CollectionUtils.isEmpty(orderParcels)) {
                wrapper.in(Order::getId, orderParcelsOIds);
            } else {
                orderParcelsOIds = orderParcels.stream().map(OrderParcel::getOrderId).collect(Collectors.toSet());
                // 创建一个外部条件，用于包含所有关键字的 OR 连接
                Set<Integer> finalOrderParcelsOIds = orderParcelsOIds;
                wrapper.and(wp -> {
                    for (Integer keyword : finalOrderParcelsOIds) {
                        wp.or(w -> {
                            w.eq(Order::getId, keyword);
                        });
                    }
                });
            }


        }

        List<String> batchNos = request.getBatchNos();
        if (CollectionUtils.isNotEmpty(batchNos)) {
            // 创建一个外部条件，用于包含所有关键字的 OR 连接
            wrapper.and(wp -> {
                for (String keyword : batchNos) {
                    wp.or(w -> {
                        w.like(Order::getBatchNo, keyword);
                    });
                }
            });
        }
        wrapper.ge(request.getBeginTime() != null, Order::getCreatedAt, request.getBeginTime());
        wrapper.le(request.getEndTime() != null, Order::getCreatedAt, request.getEndTime());

        wrapper.ge(request.getAuditBeginTime() != null, Order::getAuditorTime, request.getAuditBeginTime());
        wrapper.le(request.getAuditEndTime() != null, Order::getAuditorTime, request.getAuditEndTime());

        wrapper.orderByDesc(Order::getId);
        Page<Order> pageResult = page(page, wrapper);
        Page<GetOrdersResponse> pageResult2 = new Page<>();
        BeanUtils.copyProperties(pageResult, pageResult2);

        List<Order> orders = pageResult.getRecords();


        if (CollectionUtil.isNotEmpty(orders)) {
            Set<Integer> orderIds = orders.stream().map(Order::getId).collect(Collectors.toSet());
            Map<Integer, List<OrderParcel>> orderParcelsMap = orderParcelService.list(new LambdaQueryWrapper<OrderParcel>()
                    .in(OrderParcel::getOrderId, orderIds)).stream().collect(Collectors.groupingBy(OrderParcel::getOrderId));
            LambdaQueryWrapper<Channel> channelLambdaQueryWrapper = new LambdaQueryWrapper<>();
            Map<Integer, Channel> channelMap = channelService.list(channelLambdaQueryWrapper
                            .in(Channel::getId, orders.stream().map(Order::getChannelId).collect(Collectors.toSet())))
                    .stream().collect(Collectors.toMap(Channel::getId, Function.identity()));
            Set<String> orderNosets = orders.stream().map(Order::getOrderNo).collect(Collectors.toSet());
            List<BalanceLog> bs = balanceLogService.lambdaQuery().in(BalanceLog::getOrderNo, orderNosets)
                    .eq(BalanceLog::getType, BalanceLogType.BILLED)
                    .orderByDesc(BalanceLog::getCreatedAt)
                    .list();
            Map<String, List<BalanceLog>> bsMap = bs.stream().collect(Collectors.groupingBy(BalanceLog::getOrderNo));

            Set<Integer> userIds = orders.stream().map(Order::getUserId).collect(Collectors.toSet());

            Map<Integer, UmsAdmin> umsAdminMap = umsAdminService.list(new LambdaQueryWrapper<UmsAdmin>().in(UmsAdmin::getId, userIds)
                            .select(UmsAdmin::getId, UmsAdmin::getEmail, UmsAdmin::getRealName)).stream()
                    .collect(Collectors.toMap(UmsAdmin::getId, Function.identity()));

            // 判断当前用户是否有查看API 价格的权限
            boolean hasOriginRate = false;
            List<UmsResource> resourceList = getCacheService().getResourceList(AdminUserUtil.getUserId());
            if (CollectionUtil.isNotEmpty(resourceList)) {
                Set<String> resourceCodes = resourceList.stream().map(UmsResource::getCode).collect(Collectors.toSet());
                if (resourceCodes.contains("orderOriginRate")) {
                    hasOriginRate = true;
                }
            }
            // 管理端显示销售
            Map<Integer, UmsAdmin> sellerMap = new HashMap<>();
            if (userId == null) {
                Set<Integer> sellerIds = orders.stream().map(Order::getSellerId).filter(Objects::nonNull).collect(Collectors.toSet());
                if (CollectionUtil.isNotEmpty(sellerIds)) {
                    sellerMap = umsAdminService.list(new LambdaQueryWrapper<UmsAdmin>().in(UmsAdmin::getId, sellerIds)
                                    .select(UmsAdmin::getId, UmsAdmin::getEmail, UmsAdmin::getRealName))
                            .stream().filter(Objects::nonNull)
                            .collect(Collectors.toMap(UmsAdmin::getId, Function.identity()));
                }
            }
            Map<Integer, UmsAdmin> finalSellerMap = sellerMap;
            boolean finalHasOriginRate = hasOriginRate;
            List<GetOrdersResponse> getOrdersResponses = orders.stream().map(x -> {
                GetOrdersResponse getOrdersResponse = new GetOrdersResponse();
                BeanUtils.copyProperties(x, getOrdersResponse);
                getOrdersResponse.setParcels(orderParcelsMap.get(x.getId()));
                //账单补扣数据
                List<BalanceLog> balanceLogs = bsMap.get(x.getOrderNo());
                if (CollectionUtil.isNotEmpty(balanceLogs)) {
                    List<BilledDetailVo> billeds = balanceLogs.stream().map(b -> {
                        BilledDetailVo vo = new BilledDetailVo();
                        BeanUtils.copyProperties(b, vo);
                        return vo;
                    }).collect(Collectors.toList());
                    getOrdersResponse.setDetailVos(billeds);
                }
                Channel channel = channelMap.get(x.getChannelId());
                if (channel != null) {
                    getOrdersResponse.setServiceName(channel.getChannelName());
                    //类型
                    getOrdersResponse.setServiceCode(channel.getServiceCode());

                }

                getOrdersResponse.setUmsAdmin(umsAdminMap.get(x.getUserId()));
                getOrdersResponse.setSeller(finalSellerMap.get(x.getSellerId()));

                // 取消的订单不显示下载按钮
                Integer xStatus = x.getStatus();
                if (xStatus != null && (xStatus == OrderStatus.FAILURE.getValue() ||
                        xStatus == OrderStatus.CANCEL_ING.getValue() ||
                        xStatus == OrderStatus.CANCEL_REJECT.getValue() ||
                        xStatus == OrderStatus.CANCEL.getValue())) {
                    getOrdersResponse.setPdfUrl(null);
                }

                if (!finalHasOriginRate) { // 用户端传过来
                    getOrdersResponse.setOriginFee(null);
                }
                return getOrdersResponse;
            }).collect(Collectors.toList());
            pageResult2.setRecords(getOrdersResponses);
        }

        CommonPage<GetOrdersResponse> data = CommonPage.restPage(pageResult2);
        return data;
    }

    /**
     * 重构查询运单 下载重构了
     *
     * @param request
     * @return
     */
    @Override
    public CommonPage<GetOrdersResponse> getGetOrdersResponseCommonPageyouhua(OrderExportsRequest request) {
        Page<Order> page = new Page<>(request.getPageNum(), request.getPageSize());
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        Integer userId = request.getUserId();
        if (userId != null) { // 用户端传过来
            wrapper.eq(Order::getUserId, userId);
        } else {
            // 管理端
            UmsAdmin userInfo = AdminUserUtil.getUserInfo();
            if (userInfo.isSeller()) { // 如果是销售只能看自己或者自己相关的数据
                Integer sellerId = userInfo.getId();
                wrapper.and(wp -> {
                    wp.eq(Order::getUserId, sellerId)
                            .or().eq(Order::getSellerId, sellerId);
                });
            }
        }

        List<OrderStatus> status = request.getStatus();
        if (CollectionUtil.isNotEmpty(status)) {
//            if (OrderStatus.CANCEL2.equals(status)) {
//                wrapper.and(wp -> {
//                    wp.eq(Order::getStatus, OrderStatus.CANCEL_ING).or().eq(Order::getStatus, OrderStatus.CANCEL)
//                            .or().eq(Order::getStatus, OrderStatus.VOIDED);
//                });
//            }

            //else {
            //   wrapper.eq(Order::getStatus, status);
            // }
            wrapper.and(wp -> {
                for (OrderStatus st : status) {
                    wp.or(w -> {
                        w.eq(Order::getStatus, st.getValue());
                    });
                }
            });

        }

        List<String> requestOrderIds = request.getOrderIds();
        if (CollectionUtil.isNotEmpty(requestOrderIds)) {
            wrapper.in(Order::getId, requestOrderIds);
        }
        //渠道名称过滤条件
        wrapper.in(CollectionUtil.isNotEmpty(request.getChannelIds()), Order::getChannelId, request.getChannelIds());

        List<Integer> searchIds = new ArrayList<>();
        List<String> emails = request.getEmails();
        if (CollectionUtil.isNotEmpty(emails)) {
            LambdaQueryWrapper<UmsAdmin> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.and(wp -> {
                for (String email : emails) {
                    wp.or(w -> {
                        w.likeRight(UmsAdmin::getEmail, email);
                    });
                }
            });
            searchIds = umsAdminService.list(queryWrapper).stream().map(UmsAdmin::getId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(searchIds)) {
                searchIds = Arrays.asList(-1);
            }
        }
        wrapper.in(!searchIds.isEmpty(), Order::getUserId, searchIds);

        List<String> orderNos = request.getOrderNos();
        if (CollectionUtils.isNotEmpty(orderNos)) {
            // 创建一个外部条件，用于包含所有关键字的 OR 连接
            wrapper.and(wp -> {
                for (String keyword : orderNos) {
                    wp.or(w -> {
                        w.like(Order::getOrderNo, keyword);
                    });
                }
            });
        }

        List<String> platformNos = request.getPlatformNos();
        if (CollectionUtils.isNotEmpty(platformNos)) {
            // 创建一个外部条件，用于包含所有关键字的 OR 连接
            wrapper.and(wp -> {
                for (String keyword : platformNos) {
                    wp.or(w -> {
                        w.like(Order::getPlatformNo, keyword);
                    });
                }
            });
        }

        List<String> trackingNos = request.getTrackingNos();
        if (CollectionUtils.isNotEmpty(trackingNos)) {
            Set<Integer> orderParcelsOIds = new HashSet<>();
            orderParcelsOIds.add(-1);
            List<OrderParcel> orderParcels = orderParcelService.list(new LambdaQueryWrapper<OrderParcel>()
                    .in(OrderParcel::getTrackingNumber, trackingNos));
            if (CollectionUtils.isEmpty(orderParcels)) {
                wrapper.in(Order::getId, orderParcelsOIds);
            } else {
                orderParcelsOIds = orderParcels.stream().map(OrderParcel::getOrderId).collect(Collectors.toSet());
                // 创建一个外部条件，用于包含所有关键字的 OR 连接
                Set<Integer> finalOrderParcelsOIds = orderParcelsOIds;
                wrapper.and(wp -> {
                    for (Integer keyword : finalOrderParcelsOIds) {
                        wp.or(w -> {
                            w.eq(Order::getId, keyword);
                        });
                    }
                });
            }


        }

        List<String> batchNos = request.getBatchNos();
        if (CollectionUtils.isNotEmpty(batchNos)) {
            // 创建一个外部条件，用于包含所有关键字的 OR 连接
            wrapper.and(wp -> {
                for (String keyword : batchNos) {
                    wp.or(w -> {
                        w.like(Order::getBatchNo, keyword);
                    });
                }
            });
        }
        wrapper.ge(request.getBeginTime() != null, Order::getCreatedAt, request.getBeginTime());
        wrapper.le(request.getEndTime() != null, Order::getCreatedAt, request.getEndTime());

        wrapper.ge(request.getAuditBeginTime() != null, Order::getAuditorTime, request.getAuditBeginTime());
        wrapper.le(request.getAuditEndTime() != null, Order::getAuditorTime, request.getAuditEndTime());

        wrapper.orderByDesc(Order::getId);
        //查询
        Page<Order> pageResult = page(page, wrapper);
        Page<GetOrdersResponse> pageResult2 = new Page<>();
        BeanUtils.copyProperties(pageResult, pageResult2);

        List<Order> orders = pageResult.getRecords();


        if (CollectionUtil.isNotEmpty(orders)) {
            Set<String> oderNoSet = orders.stream().map(Order::getOrderNo).collect(Collectors.toSet());
            LambdaQueryWrapper<Channel> channelLambdaQueryWrapper = new LambdaQueryWrapper<>();
            Map<Integer, Channel> channelMap = channelService.list(channelLambdaQueryWrapper
                            .in(Channel::getId, orders.stream().map(Order::getChannelId).collect(Collectors.toSet())))
                    .stream().collect(Collectors.toMap(Channel::getId, Function.identity()));
            List<BalanceLog> bs = balanceLogService.lambdaQuery().in(BalanceLog::getOrderNo, oderNoSet)
                    .eq(BalanceLog::getType, BalanceLogType.BILLED)
                    .list();
            Map<String, List<BalanceLog>> bsMap = bs.stream().collect(Collectors.groupingBy(BalanceLog::getOrderNo));

            // 判断当前用户是否有查看API 价格的权限
            boolean hasOriginRate = false;
            List<UmsResource> resourceList = getCacheService().getResourceList(AdminUserUtil.getUserId());
            if (CollectionUtil.isNotEmpty(resourceList)) {
                Set<String> resourceCodes = resourceList.stream().map(UmsResource::getCode).collect(Collectors.toSet());
                if (resourceCodes.contains("orderOriginRate")) {
                    hasOriginRate = true;
                }
            }

            boolean finalHasOriginRate = hasOriginRate;
            List<GetOrdersResponse> getOrdersResponses = orders.stream().map(x -> {
                GetOrdersResponse getOrdersResponse = new GetOrdersResponse();
                BeanUtils.copyProperties(x, getOrdersResponse);
                //账单补扣数据
                List<BalanceLog> balanceLogs = bsMap.get(x.getOrderNo());
                if (CollectionUtil.isNotEmpty(balanceLogs)) {
                    List<BilledDetailVo> billeds = balanceLogs.stream().map(b -> {
                        BilledDetailVo vo = new BilledDetailVo();
                        BeanUtils.copyProperties(b, vo);
                        return vo;
                    }).collect(Collectors.toList());
                    getOrdersResponse.setDetailVos(billeds);
                }
                Channel channel = channelMap.get(x.getChannelId());
                if (channel != null) {
                    getOrdersResponse.setServiceName(channel.getChannelName());
                    //类型
                    getOrdersResponse.setServiceCode(channel.getServiceCode());

                }


                // 取消的订单不显示下载按钮
                Integer xStatus = x.getStatus();
                if (xStatus != null && (xStatus == OrderStatus.FAILURE.getValue() ||
                        xStatus == OrderStatus.CANCEL_ING.getValue() ||
                        xStatus == OrderStatus.CANCEL_REJECT.getValue() ||
                        xStatus == OrderStatus.CANCEL.getValue())) {
                    getOrdersResponse.setPdfUrl(null);
                }

                if (!finalHasOriginRate) { // 用户端传过来
                    getOrdersResponse.setOriginFee(null);
                }
                return getOrdersResponse;
            }).collect(Collectors.toList());
            pageResult2.setRecords(getOrdersResponses);
        }

        CommonPage<GetOrdersResponse> data = CommonPage.restPage(pageResult2);
        return data;
    }

    public UmsAdminCacheService getCacheService() {
        return SpringUtil.getBean(UmsAdminCacheService.class);
    }

    @Override
    public Integer handleOrders(String response) {
        JSONObject body = JSON.parseObject(response);
        JSONArray orderArray = JSON.parseArray(body.getString("orders"));

        for (int i = 0; i < orderArray.size(); i++) {
            JSONObject order = orderArray.getJSONObject(i);
            // 获取订单相关字段的值
            Order userOrder = new Order();
            userOrder.setOrderType(OrderType.BATCH);

            userOrder.setOrderNo(order.getString("orderId"));
            // buyer
            JSONObject buyer = order.getJSONObject("buyer");
            if (Objects.nonNull(buyer)) {
                // buyerRegistrationAddress
                JSONObject buyerRegistrationAddress = buyer.getJSONObject("buyerRegistrationAddress");
                if (Objects.nonNull(buyerRegistrationAddress)) {
                    userOrder.setFromCompany(buyerRegistrationAddress.getString("companyName"));
                    // contactAddress
                    JSONObject contactAddress = buyerRegistrationAddress.getJSONObject("contactAddress");
                    if (Objects.nonNull(contactAddress)) {
                        userOrder.setFromAddressLine1(contactAddress.getString("addressLine1"));
                        userOrder.setFromAddressLine2(contactAddress.getString("addressLine2"));
                        userOrder.setFromCity(contactAddress.getString("city"));
                        userOrder.setFromState(contactAddress.getString("county"));
                        userOrder.setFromZipCode(contactAddress.getString("postalCode"));
                        userOrder.setFromCountryCode(contactAddress.getString("county"));
                    }
                    userOrder.setFromEmail(buyerRegistrationAddress.getString("email"));
                    userOrder.setToPersonName(buyerRegistrationAddress.getString("fullName"));
                    // primaryPhone
                    JSONObject primaryPhone = buyerRegistrationAddress.getJSONObject("primaryPhone");
                    if (Objects.nonNull(primaryPhone)) {
                        userOrder.setFromPhone(primaryPhone.getString("phoneNumber"));
                    }
                }

                userOrder.setFromPersonName(buyer.getString("name"));
            }

            userOrder.setCreatedAt(LocalDateTimeUtil.now());
            this.save(userOrder);
        }

        return orderArray.size();
    }

//    @Override
//
//    public CommonResult<String> batchCreate(BatchCreateLabelOrderRequest request) {
//        List<Integer> orderIds = request.getOrderIds();
//        Integer userId = request.getUserId();
//
//
//        Integer channelId = request.getChannelId();
//        List<UserChannelVO> channels = channelService.getOnChannels(userId, null, channelId);
//        if (CollectionUtil.isEmpty(channels)) {
//            return CommonResult.failed("Permission denied");
//        }
//        UserChannelVO userChannelVO = channels.get(0);
//        Channel channel = userChannelVO.getChannel();
//        ChannelCarrier channelCarrier = channelCarrierService.getOne(new LambdaQueryWrapper<ChannelCarrier>()
//                .eq(ChannelCarrier::getId, channel.getChannelCarrierId()));
//
//        for (Integer orderId : orderIds) {
//            // 保证是最新的状态 后续下单需要加个锁或者中间状态
//            Order order = getOne(new LambdaQueryWrapper<Order>()
//                    .eq(Order::getId, orderId)
//                    .eq(userId != null, Order::getUserId, userId)
//                    .eq(Order::getStatus, OrderStatus.DRAFT));
//            if (order == null || StringUtils.isNotBlank(order.getPdfUrl())) {
//                continue;
//            }
//            EstimateRateRequest estimateRateRequest = getEstimateRateRequest(order);
//            estimateRateRequest.setChannelId(channelId);
//            fillParcel(order, channel, estimateRateRequest);
//            estimateRateRequest.setPlatformNo(EzeeShipUtil.getOrderNo());
//            estimateRateRequest.setCarrierCode(channelCarrier.getChannelCarrierCode());
//            estimateRateRequest.setServiceCode(channel.getChannelCode());
//
//            estimateRateRequest.setUserChannelVO(userChannelVO);
//            MathUtil.fmtWeight2(estimateRateRequest);
//            BaseShipService baseShipService = shipFactory.getBaseShipService(channel);
//
//            return baseShipService.createLabel(estimateRateRequest, userId);
//        }
//        return CommonResult.success();
//    }

    /**
     * 老预估
     * @param request
     * @return
     */
    @Override
    public CommonResult<EstimateRateOrderResponse> estimateRate(EstimateRateRequest request) {
        request.setIsTest(false);
        EstimateRateOrderResponse estimateRateOrderResponse = new EstimateRateOrderResponse();
        Integer userId = AdminUserUtil.getUserId();

        //根据渠道id 获取渠道列表
        List<UserChannelVO> userChannelVOS = channelService.getOnChannels(userId, request.getServiceCode(), request.getChannelId());
        if (CollectionUtil.isEmpty(userChannelVOS)) {
            log.error(userId+"没有授权渠道还在估价");
            return CommonResult.failed("user do not have authorized channel");
        }

        // 保存到草稿
        Order order = transferOrder(request);
        MathUtil.fmtWeight2(request);

        //获取预估结果 预估不出来的也要，提示要展示
        List<EstimateRateResponse.Data> results = getEstimateRateOrderResponseCommonResult(request,userId, userChannelVOS, true);

        estimateRateOrderResponse.setDatas(results);
        estimateRateOrderResponse.setOrderId(order.getId());
        return CommonResult.success(estimateRateOrderResponse);
    }



    /**
     * 新估值
     * @param request
     * @return
     */
    @Override
    public CommonResult<EstimateRateOrderResponse> estimateRateNew(EstimateRateRequest request) {
        UmsAdmin userInfo = AdminUserUtil.getUserInfo();
        Integer userId = userInfo.getId();
        request.setIsTest(false);

        //根据渠道id 获取渠道列表
        List<UserChannelVO> userChannelVOS = channelService.getOnChannelsByUserIdAndServiceCode( request.getServiceCode());
        if (CollectionUtil.isEmpty(userChannelVOS)) {
            log.error(userId+"没有授权渠道还在估价");
            return CommonResult.failed("user do not have authorized denied");
        }
        EstimateRateOrderResponse estimateRateOrderResponse = new EstimateRateOrderResponse();

        // 保存到草稿
        Order order = transferOrder(request);
        //包裹重量
        MathUtil.fmtWeight2(request);
        //从授权的渠道中选一个 有返回错的直接不要
        List<EstimateRateResponse.Data> allEstimateRateOrderResponseCommonResult = pickOneInEveryGroup(request, userId, userChannelVOS,false);
        estimateRateOrderResponse.setDatas(allEstimateRateOrderResponseCommonResult);
        estimateRateOrderResponse.setOrderId(order.getId());
        return CommonResult.success(estimateRateOrderResponse);

    }

    /**
     * 每组一个 光了提示
     * @param request
     * @param userId
     * @param userChannelVOS
     * @param isBackError 是否返回有错的
     * @return
     */
    private List<EstimateRateResponse.Data> pickOneInEveryGroup(EstimateRateRequest request, Integer userId, List<UserChannelVO> userChannelVOS,
                                                                boolean isBackError) {

        List<EstimateRateResponse.Data> allServiceCodeEstimateResultList = new ArrayList<>();
        // 按serviceCode分组
        Map<String, List<UserChannelVO>> groupedByServiceCode = userChannelVOS.stream()

                .collect(Collectors.groupingBy(userChannelVO -> userChannelVO.getChannel().getServiceCode()));

        List<EstimateRateResponse.Data> oneTypeServiceCodeEstimateResult;
        EstimateRateResponse.Data best=null;
        Map<String,List<String>> tqMap=new HashMap<>();
        for (Map.Entry<String, List<UserChannelVO>>  entry:groupedByServiceCode.entrySet()){
            //循环每一个服务分组
            String serviceCode = entry.getKey();

            //服务对应多个渠道从里面选，一种服务只展示一个
            List<UserChannelVO> userChannelByServiceCode = entry.getValue();

            //获取预估结果 不要预估不出来的
            oneTypeServiceCodeEstimateResult = getEstimateRateOrderResponseCommonResult(request, userId, userChannelByServiceCode,isBackError);

            if (CollectionUtils.isEmpty(oneTypeServiceCodeEstimateResult)){
                continue;
            }
            //如果整个类都没有成功的是错误提示不用多选一
            if ( hasNonEmptyMessage(oneTypeServiceCodeEstimateResult)){
                best = oneTypeServiceCodeEstimateResult.get(0);
            }else {
                //把授权渠道转成渠道ID对邮编+平台
                Map<Integer, Channel> resultMap = convertListToMap(userChannelByServiceCode);
                //检查偷区
                List<EstimateRateResponse.Data> data = checkTQ(request, oneTypeServiceCodeEstimateResult, resultMap,tqMap);
                //按混比多选一
                best = pickOneInSome(userId, data,  userChannelByServiceCode);
            }

            if (best!=null){
                //查询用户是否绑定了serviceCode对应的价格表关系
                long count = umsAdminPriceRuleRelationService.getIsBinding(userId, serviceCode);
                //如果此人设置了价格表，把价格替换
                if (count>0 ){
                    try {
                        //获取自定义价格
                        SelfDefinedPriceResponse selfDefinedFee = getSelfDefinedFee(request,serviceCode);
                        if (selfDefinedFee!=null){
                            log.info(serviceCode+"原价："+best.getRate()+"替换自定义价："+selfDefinedFee.getFee());
                            best.setRate(selfDefinedFee.getFee());
                            //祥情
                            best.setSurcharge(selfDefinedFee.getSurcharge());
                        }else {
                            log.error(request.getOrderNO()+"自定义价格没结果可能原因没查到zone");
                        }
                    }catch (Exception e){
                        log.error(request.getOrderNO()+"自定义价格出错");
                    }
                }
                best.setServiceCode(serviceCode);

                allServiceCodeEstimateResultList.add(best);
            }



        }

        //排序
        // 示例用法
        sortList(allServiceCodeEstimateResultList);
        return allServiceCodeEstimateResultList;


    }
    public static void sortList(List<EstimateRateResponse.Data> allServiceCodeEstimateResultList) {
        allServiceCodeEstimateResultList.sort((data1, data2) -> {
            // 如果 data1 的 messages 为空且 data2 的 messages 不为空，data1 排在前面
            if (data1.getMessages() == null && data2.getMessages()!= null) {
                return -1;
            }
            // 如果 data1 的 messages 不为空且 data2 的 messages 为空，data2 排在前面
            if (data1.getMessages()!= null && data2.getMessages() == null) {
                return 1;
            }
            // 其他情况保持原始顺序
            return 0;
        });
    }

    /**
     * 查询自定义价格表中的价格
     * @param request
     * @return
     */
    private SelfDefinedPriceResponse getSelfDefinedFee(EstimateRateRequest request,String serviceCode ) {
        SelfDefinedPriceResponse selfDefinedPriceResponse = null;
        //有绑定 查价格表
        String FzipCode = request.getFrom().getZipCode();
        String TzipCode = request.getTo().getZipCode();
        List<String> zoneList=fedexRateTool.getZone(FzipCode, TzipCode, 2);
        if (zoneList != null) {
            selfDefinedPriceResponse = new SelfDefinedPriceResponse();
            String zone = zoneList.get(0);
            //附加费列表
            List<PriceSurcharge> surchargeList = getSurcharge(selfDefinedPriceResponse,request, zone,serviceCode);
            selfDefinedPriceResponse.setSurcharge(surchargeList);

            EstimateRateRequest.Parcel param=new EstimateRateRequest.Parcel();
            //取第一个包的重量
            EstimateRateRequest.Parcel parcel = request.getParcels().get(0);
            BeanUtils.copyProperties(parcel,param);
            if (selfDefinedPriceResponse.getIsOverSize()==2){
                //oversize 单个包裹不足90磅按照90磅计费
                param.setWeight("90");
                param.setMassUnit("lb");
            }
            //从自定义价格表查价格
            PriceRule one = priceRuleService.getRateFromPriceRule(param);
            BigDecimal zoneValue = one.getZoneValue(Integer.valueOf(zone));
            BigDecimal finalzoneValue = zoneValue;
            //设置基础价格

            for (PriceSurcharge priceSurcharge : surchargeList) {
                        if (priceSurcharge.getItem().contains("Fule")){
                            BigDecimal sdf=null;
                            try {

                                  sdf = priceSurcharge.getRate();
                                if (sdf.doubleValue()!=0){
                                    BigDecimal fuleRate = zoneValue.multiply(sdf);
                                    priceSurcharge.setRate(fuleRate);
                                    zoneValue=  zoneValue.add(fuleRate);

                                }
                            }catch (Exception e){
                                log.error(sdf+"fule error"+e.getMessage());
                            }

                        }else {

                            zoneValue=  zoneValue.add(priceSurcharge.getRate());
                        }


            }
            PriceSurcharge base=new PriceSurcharge();
            base.setRate(finalzoneValue);
            base.setItem("base");
            surchargeList.add(base);
            selfDefinedPriceResponse.setFee(zoneValue);

        }
        return selfDefinedPriceResponse;
    }

    /**
     * 附加费
     * @param request
     * @param zone
     * @return
     */
    private List<PriceSurcharge> getSurcharge(SelfDefinedPriceResponse selfDefinedPriceResponse ,EstimateRateRequest request,   String zone,String serviceCode) {
        StringBuilder stringBuilder = new StringBuilder();
        //最后展示 在页面的明细
        List<PriceSurcharge> tipPriceSurchargeList=new ArrayList<>();
        //根据包裹信息获取附加费
        request.setServiceCode(serviceCode);
        List<PriceSurcharge> priceSurchargeList = priceSurchargeService.getRateFromPriceSurcharge(request,null);
        //按附加收费项分组
        Map<String, List<PriceSurcharge>> groupedByItem = priceSurchargeList.stream()
                .collect(Collectors.groupingBy(PriceSurcharge::getItem));

        String zipCode = request.getTo().getZipCode();
        EstimateRateRequest.Parcel parcel = request.getParcels().get(0);
        //长宽高
        BigDecimal parcelLength = new BigDecimal(parcel.getLength());
        BigDecimal parcelHeight = new BigDecimal(parcel.getHeight());
        BigDecimal parcelWidth = new BigDecimal(parcel.getWidth());
        BigDecimal parcelWeight = new BigDecimal(parcel.getWeight());
        if ("cm".equals(parcel.getDistanceUnit())) {
            parcelLength = MathUtil.cm2in(parcelLength);
            parcelWidth = MathUtil.cm2in(parcelWidth);
            parcelHeight = MathUtil.cm2in(parcelHeight);
        }
        if ("kg".equals(parcel.getMassUnit())) {
            parcelWeight = MathUtil.kg2lb(parcelWeight);
        }
        // 是否住宅地址
        Boolean isResidential=request.getTo().getIsResidential();
//        EstimateRateRequest.Address to = getAddress(request.getTo());
//        CommonResult validate = ezeeShipService.validate(to);
//        if (validate.isSucess()) {
//            Object data = validate.getData();
//            if (data instanceof ValidateResponse.TrackingData) {
//                  isResidential = ((ValidateResponse.TrackingData) data).getIsResidential();
//            }
//        }

        stringBuilder.append("住宅"+isResidential);
        //住宅
        if (isResidential){
            List<PriceSurcharge> re = groupedByItem.get(Constants.Residential_Charge);
            //生效
            priceSurchargeService.validSurcharge(tipPriceSurchargeList, re,serviceCode,zone,Constants.Residential_Charge);
        }
        //大小收费项
        Integer isOverSize = priceSurchargeService.checkOversizeSurcharge(selfDefinedPriceResponse, zone, serviceCode, stringBuilder, tipPriceSurchargeList, groupedByItem, parcelLength, parcelHeight, parcelWidth, parcelWeight, isResidential);
        //重量收费项
        priceSurchargeService.checkWeightSurcharge(zone, serviceCode, stringBuilder, tipPriceSurchargeList, groupedByItem, parcelWeight);

        //距离收费项
        priceSurchargeService.checkDistanceSurcharge(serviceCode, stringBuilder, tipPriceSurchargeList, groupedByItem, zipCode, isResidential);

        boolean isPeak = SurchargeTool.checkPeak();
        stringBuilder.append("峰时"+isPeak);
        //处理峰值
        if (isPeak) {
            priceSurchargeService.handlePeakConditions(groupedByItem, tipPriceSurchargeList, serviceCode, zone,isOverSize,isResidential);
        }
        //燃油费
        List<PriceSurcharge> surchargeList = groupedByItem.get(Constants.Fule);
        priceSurchargeService.validSurcharge(tipPriceSurchargeList, surchargeList, null, null,Constants.Fule);

        log.info(stringBuilder.toString()+"******************");
        return tipPriceSurchargeList;

    }


    /**
     * 检查偷取
     * @param request
     * @param oneTypeServiceCodeEstimateResult
     * @param resultMap
     */
    private  List<EstimateRateResponse.Data>  checkTQ(EstimateRateRequest request, List<EstimateRateResponse.Data> oneTypeServiceCodeEstimateResult,
                                                      Map<Integer, Channel> resultMap,Map<String,List<String>> tqMap) {
        //偷区记录channel
        List<Integer> tqcollect=new ArrayList<>();
        //只检查环洋的邮编
        List<EstimateRateResponse.Data> collect = oneTypeServiceCodeEstimateResult.stream()
                .filter(data -> resultMap.get(data.getChannelId()).getChannelPlatformId() == ChannelPlatform.MY_US_56.getValue() )
                .collect(Collectors.toList());

        if (collect.size()==0){
            //直接结束
            return oneTypeServiceCodeEstimateResult;
        }


        String fromZipCode = trimZipCode(request.getFrom().getZipCode());
        String toZipCode = trimZipCode( request.getTo().getZipCode());

        for (int i = 0; i < collect.size(); i++) {
            EstimateRateResponse.Data data = oneTypeServiceCodeEstimateResult.get(i);
            Channel channel = resultMap.get(data.getChannelId());
            String wmsFrom =channel.getPostCard();
            if (StringUtils.isBlank(wmsFrom)){
                log.error(channel.getId()+"没录邮编");
                continue;
            }
            //校验偷区07008--91744

            List<String> zone1;
            List<String> zone = null;
            String s="";
            try {
                if (tqMap.get(fromZipCode+"-"+toZipCode)==null){
                    zone1 = fedexRateTool.getZone(fromZipCode, toZipCode,3);
                    if (zone1!=null){
                        //加到map
                        tqMap.put(fromZipCode+"-"+toZipCode,zone1);
                    }
                }else {
                    zone1 = tqMap.get(fromZipCode+"-"+toZipCode);
                    log.info(fromZipCode+"-"+toZipCode+"map得到"+zone1.toString());

                }
                if (zone1!=null){

                    if (tqMap.get(wmsFrom+"-"+toZipCode)==null){
                        //走接口查
                        zone = fedexRateTool.getZone(wmsFrom, toZipCode,3);
                        if (zone!=null){
                            //加到map
                            tqMap.put(wmsFrom+"-"+toZipCode,zone);
                        }

                    }else {
                        zone = tqMap.get(wmsFrom+"-"+toZipCode);
                        log.info(fromZipCode+"-"+toZipCode+"map得到"+zone1.toString());
                    }
                }
                 s = "customer-[" + fromZipCode +"-"+ toZipCode +"]"+ zone1 + "|us-[" + wmsFrom+"-" + toZipCode+ "]"+ zone;
                if (zone!=null&&zone1!=null){
                    if (!zone1.get(0).equals(zone.get(0))||!zone1.get(1).equals(zone.get(1))){
                        log.info("偷区拦截"+data.getChannelId()+request.getOrderNO() + s);
                        tqcollect.add(data.getChannelId());
                    }else {
                        log.info("偷区拦截"+data.getChannelId()+request.getOrderNO() + s);
                    }
                }else{
                    log.error("拦截偷区失效"+request.getOrderNO() + s);
                }
            } catch (Exception e){
                log.error(data.getChannelId()+s+"查偷取接口报错"+e.getMessage());
            }
        }

        if (tqcollect.size() != 0) {
            List<EstimateRateResponse.Data> collect1 = oneTypeServiceCodeEstimateResult.stream().filter(data -> !tqcollect.contains(data.getChannelId()))
                    .collect(Collectors.toList());
            return collect1;
        } else {
            return oneTypeServiceCodeEstimateResult;
        }
    }
    /**
     * 检查偷取
     * @param request
     * @param oneTypeServiceCodeEstimateResult
     * @param resultMap
     */
    private  void checkTQinOldVersion(EstimateRateRequest request, List<EstimateRateResponse.Data> oneTypeServiceCodeEstimateResult,
                                                      Map<Integer, Channel> resultMap) {
        //偷区记录channel
        List<Integer> tqcollect=new ArrayList<>();
        //只检查环洋的邮编
        List<EstimateRateResponse.Data> collect = oneTypeServiceCodeEstimateResult.stream()
                .filter(data -> resultMap.get(data.getChannelId()).getChannelPlatformId() == ChannelPlatform.MY_US_56.getValue() )
                .collect(Collectors.toList());

        if (collect.size()==0){
            //直接结束
            return ;
        }


        String fromZipCode = trimZipCode(request.getFrom().getZipCode());
        String toZipCode = trimZipCode( request.getTo().getZipCode());
        List<String> userZone = fedexRateTool.getZone(fromZipCode, toZipCode, 3);
        if (userZone!=null){
            List<String> wmsZone;
            for (int i = 0; i < collect.size(); i++) {
                EstimateRateResponse.Data data = oneTypeServiceCodeEstimateResult.get(i);
                Channel channel = resultMap.get(data.getChannelId());
                String wmsFrom =channel.getPostCard();
                if (StringUtils.isBlank(wmsFrom)){
                    log.error(channel.getId()+"没录邮编");
                    continue;
                }
                //校验偷区07008--91744

                String s="";
                try {
                        //走接口查
                        wmsZone = fedexRateTool.getZone(wmsFrom, toZipCode,3);

                    s = "customer-[" + fromZipCode +"-"+ toZipCode +"]"+ userZone + "|us-[" + wmsFrom+"-" + toZipCode+ "]"+ wmsZone;
                    if (wmsZone!=null){
                        if (!userZone.get(0).equals(wmsZone.get(0))||!userZone.get(1).equals(wmsZone.get(1))){
                            log.info("偷区拦截成功"+data.getChannelId()+request.getOrderNO() + s);
                            tqcollect.add(data.getChannelId());
                        }else {
                            log.info("偷区检查正常"+data.getChannelId()+request.getOrderNO() + s);
                        }
                    }else{
                        log.error("订单{}偷区-仓库zone未获得{}",request.getOrderNO(), s);
                    }
                } catch (Exception e){
                    log.error(data.getChannelId()+s+"查偷取接口报错"+e.getMessage());
                }
            }
        }

        if (tqcollect.size() != 0) {
            //偷区的添加提示
            oneTypeServiceCodeEstimateResult.stream()
                    .filter(data -> tqcollect.contains(data.getChannelId()))
                    .map(data -> {
                        data.setMessages(Global.TQ_MSG);
                        return data;
                    })
                    .collect(Collectors.toList());
        }
    }

    private String trimZipCode(String zipCode) {
        if (zipCode.contains("-")) {
            String[] parts = zipCode.split("-");
            return parts[0];
        }
        return zipCode;
    }

    public static Map<Integer, Channel> convertListToMap(List<UserChannelVO> list) {
        Map<Integer, Channel> map = new HashMap<>();
        for (UserChannelVO userChannel : list) {
            map.put(userChannel.getChannelId(), userChannel.getChannel());
        }
        return map;
    }


    /**
     * 是否存在 message 不为空的条目
     * @param oneTypeServiceCodeEstimateResult
     * @return
     */
    public static boolean hasNonEmptyMessage(List<EstimateRateResponse.Data> oneTypeServiceCodeEstimateResult) {
        for (EstimateRateResponse.Data data : oneTypeServiceCodeEstimateResult) {
            if (data.getMessages()!= null &&!data.getMessages().isEmpty()) {
                return true;
            }
        }
        return false;
    }


    /**
     * 多选一
     * 原则有混比按混比，没有混默认便宜的
     *
     * @param userId
     * @param oneTypeServiceCodeEstimateResult
     * @param userChannelByServiceCode
     * @return
     */
    private EstimateRateResponse.Data pickOneInSome(Integer userId, List<EstimateRateResponse.Data> oneTypeServiceCodeEstimateResult,   List<UserChannelVO> userChannelByServiceCode) {
        if (oneTypeServiceCodeEstimateResult.isEmpty()){
            return null;
        }

        //个人混设置
        Integer userIsBest = userChannelByServiceCode.get(0).getIsBest();
        //整体
        Integer ztIsBest = userChannelByServiceCode.get(0).getChannel().getIsBest();
        if (userIsBest==0&&ztIsBest==0){
            //个人整体都是默认 已经按价格排序
            return oneTypeServiceCodeEstimateResult.get(0);
        }
         else
         {
             //整体或个人设置了混比
             //所以有结果 的渠道
             List<Integer> channelIdList = oneTypeServiceCodeEstimateResult.stream().map(EstimateRateResponse.Data::getChannelId).collect(Collectors.toList());
             // 从用户授权渠道过滤出有结果的
             List<UserChannelVO> filteredList = userChannelByServiceCode.stream()
                     .filter(userChannel -> channelIdList.contains(userChannel.getChannelId()))
                     .collect(Collectors.toList());

             // 将 platformRates 转换成目标比例数组
             int[] targetRatios = new int[filteredList.size()];
             for (int i = 0; i < filteredList.size(); i++) {
                 if (userIsBest==1){
                     //个人有按个人

                     targetRatios[i] = filteredList.get(i).getPlatformRate();
                 }else {
                     //按整体
                     targetRatios[i] = filteredList.get(i).getChannel().getPlatformRate();

                 }
             }
             //查询用户在这些渠道下单的历史比例

             List<Order> orderList = orderService.lambdaQuery()
                     .eq(Order::getUserId, userId)
                     .isNull(Order::getDeletedAt)
                     .in(Order::getChannelId, channelIdList)
                     .groupBy(Order::getChannelId)  // 添加 groupBy 条件，按照 channel_id 进行分组
                     .select(Order::getChannelId,Order::getCount)  // 选择要查询的列及聚合函数
                     .list();
             int[] hisRatios;
             hisRatios = new int[filteredList.size()];
             if (CollectionUtils.isEmpty(orderList)){
                 // 将 platformRates 转换成目标比例数组
                 for (int i = 0; i < filteredList.size(); i++) {
                     hisRatios[i] =0;
                 }
             }else {

                 // 将 platformRates 转换成目标比例数组
                 for (int i = 0; i < filteredList.size(); i++) {
                     if (i < orderList.size()) {
                         Order order = orderList.get(i);
                         if (order!= null) {
                             hisRatios[i] = order.getCount();
                         } else {
                             hisRatios[i] = 0;
                         }
                     } else {
                         hisRatios[i] = 0;
                     }
                 }
             }
             //历史订单中serviceCode相关的此用户的订单按不同的渠道比例
             int nextChannelIndex = getNextChannel(targetRatios, hisRatios);
             UserChannelVO userChannelVO = filteredList.get(nextChannelIndex);
             //这里应该只有一个
             Optional<EstimateRateResponse.Data> optionalData = oneTypeServiceCodeEstimateResult.stream()
                     .filter(xx -> userChannelVO.getChannelId().equals(xx.getChannelId()))
                     .findFirst();
             if (optionalData.isPresent()) {
                 return optionalData.get();
             }else {
                 log.error("比例后为空"+new Gson().toJson(userChannelVO));
             }

         }
        return null;
    }


    /**
     *
     * @param targetRatios 目标混比
     * @param historyOrders 历史混比
     * @return 索引
     */
    public static int getNextChannel(int[] targetRatios, int[] historyOrders) {
        int n = targetRatios.length;

        // 计算当前总订单数
        int totalOrders = Arrays.stream(historyOrders).sum() + 1;  // 加1表示下一笔订单

        // 计算每个渠道的目标数量
        double totalTarget = Arrays.stream(targetRatios).sum();
        double[] targetCounts = new double[n];
        for (int i = 0; i < n; i++) {
            targetCounts[i] = targetRatios[i] / totalTarget * totalOrders;
        }

        // 计算每个渠道与目标数量的差距
        double maxDifference = Double.NEGATIVE_INFINITY;
        int nextChannel = -1;
        try {

            for (int i = 0; i < n; i++) {
                double difference = targetCounts[i] - historyOrders[i];
                if (difference > maxDifference) {
                    maxDifference = difference;
                    nextChannel = i;
                }
            }
        }catch (Exception e){
            log.error(e.getMessage()+"混比出错");
        }

        // 返回下一个应该分配的渠道索引（从0开始）
        return nextChannel;
    }



    /**
     * 获取预估结果
     * @param request
     * @param userId 用户
     * @param userChannelVOS 用户的渠道
     * @param isBackError 是否返回错误提示的
     * @return
     */
    private   List<EstimateRateResponse.Data>  getEstimateRateOrderResponseCommonResult(EstimateRateRequest request,
                                                                                        Integer userId, List<UserChannelVO> userChannelVOS
                                                                                        ,boolean isBackError
    ) {

        List<EstimateRateResponse.Data> allDatas = new CopyOnWriteArrayList<>();
        //是否一票多件
        List<UserChannelVO> filteredUserChannelVOS = new ArrayList<>();
        boolean multiParcel = EstimateTool.isMultiParcel(request);
        if(multiParcel){
            for (UserChannelVO userChannelVO : userChannelVOS) {
                // 过滤掉 channelName 中包含 "ID：1" 的项目
                Channel channel = userChannelVO.getChannel();
                if (!channel.getChannelName().contains("ID：1")
                     &&!channel.getChannelName().contains("ID:1")
                        &&!channel.getServiceCode().startsWith("USPS")
                        &&!channel.getServiceCode().startsWith("usps")
                        &&!channel.getServiceCode().startsWith("延")
                        &&!channel.getServiceCode().startsWith("Uniuni")
                ) {
                    filteredUserChannelVOS.add(userChannelVO);
                }
            }
        }else {
            filteredUserChannelVOS=userChannelVOS;
        }
        if (filteredUserChannelVOS.size()==0){
            List<EstimateRateResponse.Data> empty=new ArrayList<>();
            EstimateRateResponse.Data notify=new EstimateRateResponse.Data();
            notify.setMessages("不支持一票多件");
            empty.add(notify);
            return empty;
        }

        //新建草稿预估费用
        List<EstimateRateResponse.Data> datas = batchEstimateRate(request, filteredUserChannelVOS, userId);
        allDatas.addAll(datas);
        //三方返回错前加3rd party:
        allDatas.stream()
                .map(data -> {
                    if (data.getMessages()!= null &&!data.getMessages().isEmpty()) {
                        data.setMessages("3rd party:" + data.getMessages());
                    }
                    return data;
                })
                .collect(Collectors.toList());

        //无错的按渠道id分组
        List<EstimateRateResponse.Data> rightList = allDatas.stream().filter(x -> StringUtils.isBlank(x.getMessages())).collect(Collectors.toList());
        Map<Integer, List<EstimateRateResponse.Data>> rightMap = allDatas.stream().filter(x -> StringUtils.isBlank(x.getMessages()))
                .collect(Collectors.groupingBy(EstimateRateResponse.Data::getChannelId));
//        Map<Integer, List<EstimateRateResponse.Data>> noMap = allDatas.stream().filter(x -> StringUtils.isNotBlank(x.getMessages()))
//                .collect(Collectors.groupingBy(EstimateRateResponse.Data::getChannelId));
//
//        List<EstimateRateResponse.Data> results = rightMap.entrySet().stream()
//                .map(entry -> {
//                    List<EstimateRateResponse.Data> values = entry.getValue();
//                    BigDecimal totalRate = BigDecimal.ZERO;
//                    for (EstimateRateResponse.Data v : values) {
//                        totalRate = totalRate.add(v.getRate());
//                    }
//                    EstimateRateResponse.Data mergedData = new EstimateRateResponse.Data();
//
//
//
//                    BeanUtils.copyProperties(values.get(0), mergedData);
//                    mergedData.setRate(totalRate);
//                    return mergedData;
//                })
//                .collect(Collectors.toList());

        //把授权渠道转成渠道ID对邮编+平台
        Map<Integer, Channel> resultMap = convertListToMap(userChannelVOS);
        checkTQinOldVersion(request,rightList,resultMap);


        List<EstimateRateResponse.Data> results = new ArrayList<>();
        for (Map.Entry<Integer, List<EstimateRateResponse.Data>> entry : rightMap.entrySet()) {
            List<EstimateRateResponse.Data> values = entry.getValue();
            BigDecimal totalRate = BigDecimal.ZERO;
            for (EstimateRateResponse.Data v : values) {
                totalRate = totalRate.add(v.getRate());
            }
            EstimateRateResponse.Data mergedData = new EstimateRateResponse.Data();
            EstimateRateResponse.Data firstValue = values.get(0);
            mergedData.setRate(totalRate);
            BeanUtils.copyProperties(firstValue, mergedData);
            results.add(mergedData);
        }


        //按价格排序
        results.sort(Comparator.comparing(data -> data.getRate()));
        if (isBackError){
            setErrors(allDatas, results);
        }else {
            if (results.size()==0){
                setErrors(allDatas, results);
            }
        }



        return results;
    }

    /**
     * 设置错误的
     * @param allDatas
     * @param results
     */
    private void setErrors(List<EstimateRateResponse.Data> allDatas, List<EstimateRateResponse.Data> results) {
        //提取msg不为空的
        List<EstimateRateResponse.Data> errors = allDatas.stream().filter(x -> StringUtils.isNotBlank(x.getMessages())).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(errors)) {
            results.addAll(errors);
        }
    }


    @NotNull
    private Order transferOrder(EstimateRateRequest request) {
        UmsAdmin userInfo = AdminUserUtil.getUserInfo();
        Order order = new Order();
        BeanUtils.copyProperties(request, order);

        Integer orderId = request.getOrderId();
        order.setId(orderId);
        if (orderId == null) {
            // 表示新增数据
            order.setUserId(userInfo.getId());
            order.setSellerId(userInfo.getSellerId());
        }

        order.setChannelId(request.getChannelId());
        checkOrderNo(request);
        order.setOrderNo(request.getOrderNO());



        if (StringUtils.isBlank(order.getOrderNo())) {
            UUID uuid4 = UUID.randomUUID();
            String orderNo = uuid4.toString().replaceAll("-", "");
            String prefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            String s = prefix + orderNo.substring(orderNo.length() - 6);
            order.setOrderNo(s);
        }
        // order.setCreateTime(LocalDateTime.now());
        order.setFromCity(request.getFrom().getCity());
        order.setFromEmail(request.getFrom().getEmail());
        order.setFromCompany(request.getFrom().getCompany());
        order.setFromPhone(request.getFrom().getPhone());
        order.setFromAddressLine2(request.getFrom().getAddressLine2());
        order.setFromAddressLine1(request.getFrom().getAddressLine1());
        order.setFromCountryCode(request.getFrom().getCountryCode());
        order.setFromZipCode(request.getFrom().getZipCode());
        order.setFromPersonName(request.getFrom().getPersonName());
        order.setFromStateCode(request.getFrom().getStateCode());

        EstimateRateRequest.Address requestTo = request.getTo();
        order.setToCity(requestTo.getCity());
        order.setToEmail(requestTo.getEmail());
        order.setToCompany(requestTo.getCompany());
        order.setToPhone(requestTo.getPhone());
        order.setToAddressLine2(requestTo.getAddressLine2());
        order.setToAddressLine1(requestTo.getAddressLine1());
        order.setToCountryCode(requestTo.getCountryCode());
        order.setToZipCode(requestTo.getZipCode());
        order.setToPersonName(requestTo.getPersonName());
        order.setToStateCode(requestTo.getStateCode());
        order.setStatus(OrderStatus.DRAFT.getValue());
        order.setOrderType(OrderType.CREATE);

        if (BooleanUtil.isTrue(requestTo.getIsValid())) {
            order.setValidateStatus(ValidateStatus.defaultEnum(requestTo.getIsResidential()));
        } else {
            order.setValidateStatus(ValidateStatus.UN_VALIDATE);
        }

        EstimateRateRequest.LabelExtra extra = request.getExtra();
        if (extra != null) {
            order.setReference(extra.getReference());
            order.setReference2(extra.getReference2());
            if (extra.getBatteryType()!=null){

                order.setBatteryType(extra.getBatteryType());
            }
        }


        return order;
    }

    /**
     *
     * 新建草稿单个预估费用
     * @param request
     * @param userChannelVOList
     * @param userId
     * @return
     */
    @NotNull
    private List<EstimateRateResponse.Data> batchEstimateRate(EstimateRateRequest request, List<UserChannelVO> userChannelVOList, Integer userId) {
        Set<Integer> carrierIdSet = userChannelVOList.stream().map(UserChannelVO::getChannel).map(Channel::getChannelCarrierId).collect(Collectors.toSet());
        //查询货运商
        Map<Integer, ChannelCarrier> channelCarrierMap = channelCarrierService.list(new LambdaQueryWrapper<ChannelCarrier>()
                        .in(ChannelCarrier::getId, carrierIdSet))
                .stream().collect(Collectors.toMap(ChannelCarrier::getId, Function.identity()));
        List<EstimateRateResponse.Data> datas = new CopyOnWriteArrayList<>();
        final CountDownLatch countDownLatch = new CountDownLatch(userChannelVOList.size());

        for (UserChannelVO userChannelVO : userChannelVOList) {
            Channel channel = userChannelVO.getChannel();
            if (channel == null) {
                log.error(userChannelVO.getUserId()+"对应的渠道id"+userChannelVO.getChannelId()+"渠道信息为空");
                countDownLatch.countDown();
                continue;
            }
            //获取对应的货运商
            ChannelCarrier channelCarrier = channelCarrierMap.get(channel.getChannelCarrierId());
            request.setServiceCode(channel.getChannelCode());
            request.setCarrierCode(channelCarrier.getChannelCarrierCode());
            request.setChannelId(channel.getId());
            EstimateRateRequest localRequest = new EstimateRateRequest();
            BeanUtils.copyProperties(request, localRequest);
            localRequest.setUserChannelVO(userChannelVO);
            ezeeShipThreadPool.execute(() -> {
                try {
                    BaseShipService baseShipService = shipFactory.getBaseShipService(channel);
                    //估价
                    CommonResult commonResult = baseShipService.estimateRate(localRequest, userId);

                    Object data = commonResult.getData();
                    EstimateRateResponse.Data tmp;
                    if (data instanceof EstimateRateResponse.Data) {
                        tmp = (EstimateRateResponse.Data) data;
                        //设置到达时间
                        tmp.setDeliveryTime(CommonUtil.getDeliveryTime(channel));
                    } else {
                        tmp = new EstimateRateResponse.Data();
                        tmp.setRate(BigDecimal.ZERO);
                        tmp.setMessages(commonResult.getMessage());

                    }
                    tmp.setCarrierServiceName(channel.getChannelName());
                    tmp.setCarrierServiceCode(channel.getChannelCode());
                    tmp.setChannelId(channel.getId());
                    if (channelCarrier != null) {
                        tmp.setCarrierCode(channelCarrier.getChannelCarrierCode());
                        tmp.setCarrierName(channelCarrier.getChannelCarrierName());
                    }
                    if (tmp.getRate().compareTo(BigDecimal.ZERO)==0&&StringUtils.isBlank(tmp.getMessages())){
                        tmp.setMessages("当前渠道暂不可用");
                    }
                    datas.add(tmp);
                } catch (Exception e) {
                    EstimateRateResponse.Data tmp = new EstimateRateResponse.Data();
                    tmp.setRate(BigDecimal.ZERO);
                    tmp.setCarrierServiceName(channel.getChannelName());
                    tmp.setCarrierServiceCode(channel.getChannelCode());
                    tmp.setMessages(e.getMessage());
                    datas.add(tmp);
                    e.printStackTrace();
                } finally {
                    countDownLatch.countDown();
                }
            });

        }

        try {
            // 等待这个批次的所有任务完成
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return datas;
    }

    @Override
    public CommonResult<List<BatchEstimateRateResponse>> batchEstimateRate(BatchEstimateRateRequest request) {
        List<BatchEstimateRateResponse> batchEstimateRateResponses = new ArrayList<>();
        //批量预估 校验不在草稿状态的不可批量预估
        List<Order> orders = list(new LambdaQueryWrapper<Order>()
                .eq(Order::getStatus, OrderStatus.DRAFT)
                .in(Order::getId, request.getOrderIds()));
        if (CollectionUtil.isEmpty(orders)) {
            return CommonResult.failed("the order not in draft can not batchEstimateRate");
        }
        //通过serviceCode查询可用的渠道
        Integer channelId = request.getChannelId();
        //判断用户是否有渠道权限
        for (Order order : orders) {
            List<UserChannelVO> orderChannelVo = channelService.getOnChannels(order.getUserId(), null, channelId);
            if (CollectionUtil.isEmpty(orderChannelVo)) {
                return CommonResult.failed("the channel is not in service");
            }
        }
        Set<Integer> orderIdSet = orders.stream().map(Order::getId).collect(Collectors.toSet());


        //两个国家不相等的查清关

            // 清关信息 只有两个国家code不同才查询
            List<UserOrderInter> userOrderInter = userOrderInterService.lambdaQuery()
                    .in(UserOrderInter::getOrderId,orderIdSet)
                    .list();
        Map<Integer, UserOrderInter> userOrderInterMap = userOrderInter.stream().collect(Collectors.toMap(UserOrderInter::getOrderId, Function.identity()));


        Channel channel = channelService.getById(channelId);
        for (Order order : orders) {
            //获取清关
            UserOrderInter orderInter = userOrderInterMap.get(order.getId());

            EstimateRateRequest estimateRateRequest = getEstimateRateRequest(order,orderInter);
            estimateRateRequest.setChannelId(channelId);
            fillParcel(order, channel, estimateRateRequest);

            ChannelCarrier channelCarrier = channelCarrierService.getOne(new LambdaQueryWrapper<ChannelCarrier>()
                    .eq(ChannelCarrier::getId, channel.getChannelCarrierId()));

            estimateRateRequest.setCarrierCode(channelCarrier.getChannelCarrierCode());
            estimateRateRequest.setServiceCode(channel.getChannelCode());
            //批量预估就是循环在走单个预估
            CommonResult<EstimateRateOrderResponse> estimateRateOrderResponseCommonResult = estimateRate(estimateRateRequest);
            EstimateRateOrderResponse estimateRateOrderResponse = estimateRateOrderResponseCommonResult.getData();
            List<EstimateRateResponse.Data> datas = estimateRateOrderResponse.getDatas();
            if (CollectionUtil.isNotEmpty(datas)) {
                EstimateRateResponse.Data data = datas.get(0);
                BatchEstimateRateResponse batchEstimateRateResponse = new BatchEstimateRateResponse();
                batchEstimateRateResponse.setOrderId(order.getId());
                batchEstimateRateResponse.setOrderNo(order.getOrderNo());
                BigDecimal rate = data.getRate();
                order.setRate(rate);
                order.setCarrierCode(channelCarrier.getChannelCarrierCode());
                updateById(order);

                batchEstimateRateResponse.setRate(rate);
                batchEstimateRateResponse.setMessages(data.getMessages());
                batchEstimateRateResponses.add(batchEstimateRateResponse);
            }
        }
        return CommonResult.success(batchEstimateRateResponses);
    }

    /**
     * 没有指定的渠道了 只有servicecode
     * @param request
     * @return
     */
    @Override
    public CommonResult<List<BatchEstimateRateResponse>> batchEstimateRateNew(BatchEstimateRateRequest request) {
        UmsAdmin userInfo = AdminUserUtil.getUserInfo();
        Integer userId = userInfo.getId();
        List<BatchEstimateRateResponse> batchEstimateRateResponses = new ArrayList<>();
        //校验订单状态是否是草稿
        List<Order> orders = list(new LambdaQueryWrapper<Order>()
                .eq(Order::getStatus, OrderStatus.DRAFT)
                .in(Order::getId, request.getOrderIds()));
        if (CollectionUtil.isEmpty(orders)) {
            return CommonResult.failed("the order not in draft can not batchCreate");
        }
        //通过serviceCode查询可用的渠道
        List<UserChannelVO> userChannelVOS = channelService.getOnChannelsByUserIdAndServiceCode(
        request.getServiceCode());
        if (CollectionUtil.isEmpty(userChannelVOS)) {
            log.error(userId+"没有授权渠道还在估价");//
            return CommonResult.failed("user do not have authorized denied");
        }
        List<UserChannelVO> EZEE_SHIPChannelVOS=new ArrayList<>();
        List<UserChannelVO> nomalUserChannelVOS=new ArrayList<>();
        userChannelVOS.forEach(x->{
            Integer channelPlatformId = x.getChannelPlatformId();
            if (ChannelPlatform.EZEE_SHIP.getValue() == channelPlatformId) {
                EZEE_SHIPChannelVOS.add(x);
            }else {
                nomalUserChannelVOS.add(x);
            }
        });

        for (Order order : orders) {
            EstimateRateRequest estimateRateRequest = getEstimateRateRequest(order,null);
            List<EstimateRateResponse.Data> allDatas = new ArrayList<>();
            List<EstimateRateResponse.Data> datas = null;
            List<EstimateRateResponse.Data> ezdatas=null;
            if (nomalUserChannelVOS.size()!=0){

                //预估得要三方公司查包裹
                fillNomalParcel(order,  estimateRateRequest);

                //批量预估就是循环在走单个预估再从授权的渠道中选一个
                 datas = pickOneInEveryGroup(estimateRateRequest, userId, nomalUserChannelVOS,true);
            }
            if (EZEE_SHIPChannelVOS.size()!=0){
                //预估得要三方公司查包裹
                fillezParcel(order,  estimateRateRequest);
                ezdatas = pickOneInEveryGroup(estimateRateRequest, userId, EZEE_SHIPChannelVOS,true);
            }
            if (CollectionUtils.isNotEmpty(ezdatas)&&CollectionUtils.isNotEmpty(datas)){
                //预估得要三方公司查包裹
                EstimateRateResponse.Data data = ezdatas.get(0);
                EstimateRateResponse.Data data1 = datas.get(0);
                if (data.getRate().compareTo(data1.getRate())>0){
                    allDatas.add(data1);
                }else {
                    allDatas.add(data);
                }
             }
            else if (CollectionUtils.isNotEmpty(datas)){
                allDatas.addAll(datas);
            }else if (CollectionUtils.isNotEmpty(ezdatas)){
                allDatas.addAll(ezdatas);

            }

            if (CollectionUtil.isNotEmpty(allDatas)) {

                EstimateRateResponse.Data data = allDatas.get(0);
                BatchEstimateRateResponse batchEstimateRateResponse = new BatchEstimateRateResponse();
                batchEstimateRateResponse.setOrderId(order.getId());
                batchEstimateRateResponse.setOrderNo(order.getOrderNo());
                BigDecimal rate = data.getRate();
                order.setRate(rate);
                order.setCarrierCode(data.getCarrierCode());
//                order.setCarrierCode(channelCarrier.getChannelCarrierCode());
                updateById(order);

                batchEstimateRateResponse.setRate(rate);
                batchEstimateRateResponse.setChannelId(data.getChannelId());
                batchEstimateRateResponse.setMessages(data.getMessages());
                batchEstimateRateResponses.add(batchEstimateRateResponse);
            }
        }
        return CommonResult.success(batchEstimateRateResponses);
    }

    @Override
    public CommonResult<String> downLabel(OrderCancelRequest request) {

        Integer userId = request.getUserId();

        List<String> orderIds = request.getOrderIds();
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<Order>()
                .eq(userId != null, Order::getUserId, userId)
                .in(Order::getId, orderIds)
                .orderByDesc(Order::getId);
        List<Order> orders = list(queryWrapper);
        if (CollectionUtil.isEmpty(orders)) {
            return CommonResult.failed("no order found");
        }

        //Map<String, String> pdfMap = orders.stream().collect(Collectors.toMap(Order::getOrderNo, Order::getPdfUrl, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
        // uni不一样将uni过滤掉单独处理
        // 批量拿channel信息，避免for里面一次一次拿 频繁连接数据库关闭数据库
        List<Channel> channels = channelService.list(new LambdaQueryWrapper<Channel>()
                .in(Channel::getId, orders.stream().map(Order::getChannelId).collect(Collectors.toList()))
                .select(Channel::getId, Channel::getServiceCode));
        // 这里先写死 可以建常量 从常量里取 如果后期变更 只需要改常量里的所有用到的地方就可以不改
        // 拿到类型是Uniuni的channel
        String uniType = "Uniuni";
        List<Channel> uniChannelList = Optional.ofNullable(channels).orElse(Lists.newArrayList())
                .stream().filter(channel -> channel.getServiceCode().equals(uniType)).collect(Collectors.toList());
        // 不是uni的订单
        Map<String, String> pdfMap = orders.stream()
                .filter(order -> uniChannelList.stream().noneMatch(channel -> channel.getId().equals(order.getChannelId()))).collect(Collectors.toMap(Order::getOrderNo, Order::getPdfUrl, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
        // uni的订单
        List<Order> uniOrders = orders.stream().filter(order -> uniChannelList.stream().anyMatch(channel -> channel.getId().equals(order.getChannelId()))).collect(Collectors.toList());
        log.info("不是uni的订单:{}, uni的订单:{}", pdfMap, uniOrders);
        Map<Integer, String> orderTraNumMap = MapUtil.newHashMap();
        if (CollectionUtil.isNotEmpty(uniOrders)) {
            List<OrderParcel> orderParcels = Optional.ofNullable(
                    orderParcelService.list(new LambdaQueryWrapper<OrderParcel>()
                            .in(OrderParcel::getOrderId, uniOrders.stream().map(Order::getId).collect(Collectors.toSet()))
                                    .select(OrderParcel::getTrackingNumber, OrderParcel::getOrderId)
                            .orderByAsc(OrderParcel::getOrderId))
            ).orElse(Lists.newArrayList());
            orderTraNumMap = orderParcels.stream().collect(Collectors.toMap(OrderParcel::getOrderId, OrderParcel::getTrackingNumber));
        }
        log.info("traNumMap:{}", orderTraNumMap);


        PDFMergerUtility pdfMerger = new PDFMergerUtility();
        String tempDir = System.getProperty("java.io.tmpdir");
        String fileName = LocalDateTime.now().toString().replace(":", "_") + ".pdf";
        String zipFilePath = tempDir + File.separator + fileName;

        try {
            for (Map.Entry<String, String> et : pdfMap.entrySet()) {
                String orderNo = et.getKey();
                String pdrUrl = et.getValue();
                ResponseEntity<byte[]> response = restTemplate.exchange(
                        pdrUrl, HttpMethod.GET, null, byte[].class);

                File file = new File(tempDir + File.separator + orderNo + ".pdf");
                try (FileOutputStream fos = new FileOutputStream(file)) {
                    fos.write(response.getBody());
                }

                pdfMerger.addSource(file);
            }

            //uni的也加入到pdfMerger
            for (Order uniOrder : uniOrders) {
                String trackingNumber = orderTraNumMap.get(uniOrder.getId());
                String uniResponse = uniUniRequest.printLabel(new UniPrintLabelReqDTO()
                        .setPackageId(trackingNumber).setLabelType(6).setLabelFormat("pdf").setType("base64"));
                UniPrintPdtResponse uniPrintPdtResponse = JSONObject.parseObject(uniResponse, UniPrintPdtResponse.class);
                String errorCode = Optional.ofNullable(uniPrintPdtResponse.getErrCode()).orElse("");
                if (errorCode.equals("0")) {
                    List<UniPrintLabel> uniPrintLabelList = JSONObject.parseObject(uniPrintPdtResponse.getData(), new TypeReference<List<UniPrintLabel>>() {
                    });
                    // 测试返回多个base64
                    /*UniPrintLabel uniPrintLabel2 = new UniPrintLabel();
                    uniPrintLabel2.setLabelContent("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NzA4IDYyNSA1NzEgNTQ5IDY1OSA2MTUgODkwIDYxNiA1NDkgNjE2IDM1MSAzMDMgMzUxIDc1NCA0NTAgNDUwIDU1MSA1NzEgNDk1IDU3MSA1NTQgMzE2IDU3MSA1NzAgMjUwIDI1MCA1MjEgMjUwIDg3NiA1NzAgNTUwIDU3MSA1NzEgMzcwIDQ2OSAzNTMgNTcwIDUzMiA3MzYgNTMyIDUzMiA0NzIgNTcyIDMwMyA1NzIgNzU0IF0KIF0KL0NJRFRvR0lETWFwIDEyIDAgUgo+PgplbmRvYmoKOSAwIG9iago8PC9MZW5ndGggMzQ2Pj4Kc3RyZWFtCi9DSURJbml0IC9Qcm9jU2V0IGZpbmRyZXNvdXJjZSBiZWdpbgoxMiBkaWN0IGJlZ2luCmJlZ2luY21hcAovQ0lEU3lzdGVtSW5mbwo8PC9SZWdpc3RyeSAoQWRvYmUpCi9PcmRlcmluZyAoVUNTKQovU3VwcGxlbWVudCAwCj4+IGRlZgovQ01hcE5hbWUgL0Fkb2JlLUlkZW50aXR5LVVDUyBkZWYKL0NNYXBUeXBlIDIgZGVmCjEgYmVnaW5jb2Rlc3BhY2VyYW5nZQo8MDAwMD4gPEZGRkY+CmVuZGNvZGVzcGFjZXJhbmdlCjEgYmVnaW5iZnJhbmdlCjwwMDAwPiA8RkZGRj4gPDAwMDA+CmVuZGJmcmFuZ2UKZW5kY21hcApDTWFwTmFtZSBjdXJyZW50ZGljdCAvQ01hcCBkZWZpbmVyZXNvdXJjZSBwb3AKZW5kCmVuZAoKZW5kc3RyZWFtCmVuZG9iagoxMCAwIG9iago8PC9SZWdpc3RyeSAoQWRvYmUpCi9PcmRlcmluZyAoVUNTKQovU3VwcGxlbWVudCAwCj4+CmVuZG9iagoxMSAwIG9iago8PC9UeXBlIC9Gb250RGVzY3JpcHRvcgovRm9udE5hbWUgL01QREZBQStEZWphVnVTYW5zQ29uZGVuc2VkCiAvQ2FwSGVpZ2h0IDcyOQogL1hIZWlnaHQgNTQ3CiAvRm9udEJCb3ggWy05MTggLTQ2MyAxNjE0IDEyMzJdCiAvRmxhZ3MgNAogL0FzY2VudCA5MjgKIC9EZXNjZW50IC0yMzYKIC9MZWFkaW5nIDAKIC9JdGFsaWNBbmdsZSAwCiAvU3RlbVYgODcKIC9NaXNz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IDQxMSA3NTQgNDUwIDQ1MCA2MDcgNjQ0IDUzMyA2NDQgNjEwIDM5MSA2NDQgNjQxIDMwOCAzMDggNTk4IDMwOCA5MzggNjQxIDYxOCA2NDQgNjQ0IDQ0NCA1MzYgNDMwIDY0MSA1ODYgODMxIDU4MCA1ODYgNTIzIDY0MSAzMjkgNjQxIDc1NCBdCiBdCi9DSURUb0dJRE1hcCAxOSAwIFIKPj4KZW5kb2JqCjE2IDAgb2JqCjw8L0xlbmd0aCAzNDY+PgpzdHJlYW0KL0NJREluaXQgL1Byb2NTZXQgZmluZHJlc291cmNlIGJlZ2luCjEyIGRpY3QgYmVnaW4KYmVnaW5jbWFwCi9DSURTeXN0ZW1JbmZvCjw8L1JlZ2lzdHJ5IChBZG9iZSkKL09yZGVyaW5nIChVQ1MpCi9TdXBwbGVtZW50IDAKPj4gZGVmCi9DTWFwTmFtZSAvQWRvYmUtSWRlbnRpdHktVUNTIGRlZgovQ01hcFR5cGUgMiBkZWYKMSBiZWdpbmNvZGVzcGFjZXJhbmdlCjwwMDAwPiA8RkZGRj4KZW5kY29kZXNwYWNlcmFuZ2UKMSBiZWdpbmJmcmFuZ2UKPDAwMDA+IDxGRkZGPiA8MDAwMD4KZW5kYmZyYW5nZQplbmRjbWFwCkNNYXBOYW1lIGN1cnJlbnRkaWN0IC9DTWFwIGRlZmluZXJlc291cmNlIHBvcAplbmQKZW5kCgplbmRzdHJlYW0KZW5kb2JqCjE3IDAgb2JqCjw8L1JlZ2lzdHJ5IChBZG9iZSkKL09yZGVyaW5nIChVQ1MpCi9TdXBwbGVtZW50IDAKPj4KZW5kb2JqCjE4IDAgb2JqCjw8L1R5cGUgL0ZvbnREZXNjcmlwdG9yCi9Gb250TmFtZSAvTVBERkFBK0RlamFWdVNhbnNDb25kZW5zZWQtQm9sZAogL0NhcEhlaWdodCA3MjkKIC9YSGVpZ2h0IDU0NwogL0ZvbnRCQm94IFstOTYyIC00MTUgMTc3NyAxMTc1XQogL0ZsYWdzIDI2MjE0OAogL0FzY2VudCA5MjgKIC9EZXNjZW50IC0yMzYKIC9MZWFkaW5nIDAKIC9JdGFsaWNBbmdsZSAwCiAvU3RlbVYgMTY1CiAvTWlzc2luZ1dpZHRoIDU0MAogL1N0eWxlIDw8IC9QYW5vc2UgPCAw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b250IC9NUERGQUErRGVqYVZ1U2Fuc0NvbmRlbnNlZC1Cb2xkT2JsaXF1ZQovRW5jb2RpbmcgL0lkZW50aXR5LUgKL0Rlc2NlbmRhbnRGb250cyBbMjIgMCBSXQovVG9Vbmljb2RlIDIzIDAgUgo+PgplbmRvYmoKMjIgMCBvYmoKPDwvVHlwZSAvRm9udAovU3VidHlwZSAvQ0lERm9udFR5cGUyCi9CYXNlRm9udCAvTVBERkFBK0RlamFWdVNhbnNDb25kZW5zZWQtQm9sZE9ibGlxdWUKL0NJRFN5c3RlbUluZm8gMjQgMCBSCi9Gb250RGVzY3JpcHRvciAyNSAwIFIKL0RXIDU0MAovVyBbIDMyIFsgMzEzIDQxMCA0NjkgNjI2IDYyNiA5MDEgNzg1IDI3NSA0MTEgNDExIDQ3MCA3NTQgMzQyIDM3NCAzNDIgMzI5IF0KIDQ4IDU3IDYyNiA1OCA1OSAzNjAgNjAgNjIgNzU0IDYzIFsgNTIyIDkwMCA2OTYgNjg2IDY2MCA3NDcgNjE1IDYxNSA3MzggNzUzIDMzNCAzMzQgNjk3IDU3MyA4OTYgNzUzIDc2NSA2NTkgNzY1IDY5MyA2NDggNjE0IDczMCA2OTYgOTkzIDY5NCA2NTEgNjUyIDQxMSAzMjkgNDExIDc1NCA0NTAgNDUwIDYwNyA2NDQgNTMzIDY0NCA2MTAgMzkxIDY0NCA2NDEgMzA4IDMwOCA1OTggMzA4IDkzOCA2NDEgNjE4IDY0NCA2NDQgNDQ0IDUzNiA0MzAgNjQxIDU4NiA4MzEgNTgwIDU4NiA1MjMgNjQxIDMyOSA2NDEgNzU0IF0KIF0KL0NJRFRvR0lETWFwIDI2IDAgUgo+PgplbmRvYmoKMjMgMCBvYmoKPDwvTGVuZ3RoIDM0Nj4+CnN0cmVhbQovQ0lESW5pdCAvUHJvY1NldCBmaW5kcmVzb3VyY2UgYmVnaW4KMTIgZGljdCBiZWdpbgpiZWdpbmNtYXAKL0NJRFN5c3RlbUluZm8KPDwvUmVnaXN0cnkgKEFkb2JlKQovT3JkZXJpbmcgKFVDUykKL1N1cHBsZW1lbnQgMAo+PiBkZWYKL0NNYXBOYW1lIC9BZG9iZS1JZGVudGl0eS1VQ1MgZGVmCi9DTWFwVHlwZSAyIGRlZgoxIGJlZ2luY29kZXNw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MDAwMDI0MTQgMDAwMDAgbiAKMDAwMDAwMjQ4MyAwMDAwMCBuIAowMDAwMDAyNzkwIDAwMDAwIG4gCjAwMDAwMDMxNjYgMDAwMDAgbiAKMDAwMDAxNDc2OSAwMDAwMCBuIAowMDAwMDE0OTI3IDAwMDAwIG4gCjAwMDAwMTU0NzIgMDAwMDAgbiAKMDAwMDAxNTg2OCAwMDAwMCBuIAowMDAwMDE1OTM3IDAwMDAwIG4gCjAwMDAwMTYyNTUgMDAwMDAgbiAKMDAwMDAxNjYzMSAwMDAwMCBuIAowMDAwMDI4NzU1IDAwMDAwIG4gCjAwMDAwMjg5MjAgMDAwMDAgbiAKMDAwMDAyOTQ3MiAwMDAwMCBuIAowMDAwMDI5ODY4IDAwMDAwIG4gCjAwMDAwMjk5MzcgMDAwMDAgbiAKMDAwMDAzMDI2NCAwMDAwMCBuIAowMDAwMDMwNjQwIDAwMDAwIG4gCjAwMDAwNDI4ODQgMDAwMDAgbiAKMDAwMDA0NDQ1MyAwMDAwMCBuIAowMDAwMDQ0NzU0IDAwMDAwIG4gCjAwMDAwNDUwOTcgMDAwMDAgbiAKMDAwMDA0NTE4MSAwMDAwMCBuIAowMDAwMDQ1NjM5IDAwMDAwIG4gCjAwMDAwNDYxNjggMDAwMDAgbiAKMDAwMDA0NjQ2NCAwMDAwMCBuIAp0cmFpbGVyCjw8Ci9TaXplIDM2Ci9Sb290IDM1IDAgUgovSW5mbyAzNCAwIFIKL0lEIFs8OWEzMmMwMDVjMGI0OTU0ZjExNWFkZmI0YTRkYjUwODE+IDw5YTMyYzAwNWMwYjQ5NTRmMTE1YWRmYjRhNGRiNTA4MT5dCj4+CnN0YXJ0eHJlZgo0NjU4OAolJUVPRg==");
                    uniPrintLabelList.add(uniPrintLabel2);*/
                    for (UniPrintLabel uniPrintLabel : uniPrintLabelList) {
                        String labelContent = uniPrintLabel.getLabelContent();
                        // 将 Base64 解码为字节数组
                        byte[] bytes = Base64.getDecoder().decode(labelContent);
                        File file = new File(tempDir + File.separator + uniOrder.getOrderNo() + ".pdf");
                        try (FileOutputStream fos = new FileOutputStream(file)) {
                            fos.write(bytes);
                        }
                        pdfMerger.addSource(file);
                    }

                }
            }

            pdfMerger.setDestinationFileName(zipFilePath);
            pdfMerger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
            System.out.println("PDF 文件已合并并保存到：" + zipFilePath);
            String s = Global.DOWNLOAD_BY_FILE_NAME_API + fileName;
            ossUtil.uploadWithExpiration("pdf", fileName, new File(zipFilePath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        String newPdfUrl = Global.PRINT_LABEL_API + fileName.substring(0, fileName.length() - 4);

        return CommonResult.success(newPdfUrl);
    }

    /**
     * 下载面单
     * @param request
     * @return
     */
    @Override
    public CommonResult<String> download(OrderExportsRequest request) {
        UmsAdmin userInfo = AdminUserUtil.getUserInfo();
        request.setPageSize(999999);
        request.setPageNum(1);
        //查询
        CommonPage<GetOrdersResponse> orderResponse = getGetOrdersResponseCommonPageyouhua(request);
        List<GetOrdersResponse> orderResponseList = orderResponse.getList();
        //结果不为空
        if (!CollectionUtil.isEmpty(orderResponseList)) {

            Set<Integer> orderIds = orderResponseList.stream().map(Order::getId).collect(Collectors.toSet());

            Set<Integer> userIds = orderResponseList.stream().map(Order::getUserId).collect(Collectors.toSet());
            Set<Integer> sellers = orderResponseList.stream().map(Order::getSellerId).collect(Collectors.toSet());
            userIds.addAll(sellers);

            LambdaQueryWrapper<OrderParcel> queryWrapper = new LambdaQueryWrapper<OrderParcel>()
                    .in(OrderParcel::getOrderId, orderIds);
            List<OrderParcel> orderParcelList = orderParcelService.list(queryWrapper);
            Map<Integer, List<OrderParcel>>   orderParcelsMap = orderParcelList.stream().collect(Collectors.groupingBy(OrderParcel::getOrderId));



            Map<Integer, UmsAdmin> umsAdminMap = umsAdminService.list(new LambdaQueryWrapper<UmsAdmin>().in(UmsAdmin::getId, userIds)
                    .select(UmsAdmin::getId, UmsAdmin::getEmail, UmsAdmin::getRealName)).stream()
                    .collect(Collectors.toMap(UmsAdmin::getId, Function.identity()));



            List<ExcelOrderExport> excelOrders = buildAdminExOrderExports(orderResponseList,umsAdminMap,orderParcelsMap);
            // 只有超级管理员才能导出API成本价这个字段 单角色系统 只会有一条 取第一个就行
            List<UmsAdminRoleRelation> list = adminRoleRelationService.list(new LambdaQueryWrapper<UmsAdminRoleRelation>()
                    .eq(UmsAdminRoleRelation::getAdminId, userInfo.getId())
                    .select(UmsAdminRoleRelation::getRoleId));
            List<Integer> roleIds = list.stream().map(UmsAdminRoleRelation::getRoleId).collect(Collectors.toList());
            String s = "";
            if (CollectionUtil.isNotEmpty(roleIds)) {
                Integer roleId = roleIds.get(0);
                if (roleId.equals(Roles.ADMIN.getValue())) {
                    // 超级管理员 导出增加api成本价字段
                    s = staticController.exports(excelOrders, AdminExcelOrderExport.class);
                } else {
                    s = staticController.exports(excelOrders, ExcelOrderExport.class);
                }
            }
            return CommonResult.success(s);
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult<String> downLabel2(OrderExportsRequest request) {
        //查询订单数据
        List<Order> orders = lambdaQuery().in(Order::getId, request.getOrderIds()).orderByDesc(Order::getId).list();
        if (!CollectionUtil.isEmpty(orders)) {
            Map<Integer, String> pdfMap = new HashMap<>();
            Set<Integer> orderIdSet = orders.stream().map(Order::getId).collect(Collectors.toSet());
            List<OrderParcel> orderParcels = orderParcelService.list(new LambdaQueryWrapper<OrderParcel>()
                    .in(OrderParcel::getOrderId, orderIdSet)
                    .orderByAsc(OrderParcel::getOrderId)
            );
            for (OrderParcel orderParcel : orderParcels) {
                String trackingNumber = orderParcel.getTrackingNumber();
                if (StringUtils.isNotBlank(trackingNumber)) {
                    pdfMap.put(orderParcel.getOrderId(), trackingNumber);
                }
            }

            String fileName = LocalDateTime.now().toString().replace(":", "_") + ".zip";
            String tempDir = System.getProperty("java.io.tmpdir");
            String zipFilePath = tempDir + File.separator + fileName;

            // 批量拿channel信息，避免for里面一次一次拿 频繁连接数据库关闭数据库
            List<Integer> channelIdList = orders.stream().map(Order::getChannelId).collect(Collectors.toList());
            List<Channel> channels = channelService.list(new LambdaQueryWrapper<Channel>()
                    .in(Channel::getId, channelIdList)
                    .select(Channel::getId, Channel::getServiceCode, Channel::getChannelPlatformId));
            // 这里先写死 可以建常量 从常量里取 如果后期变更 只需要改常量里的所有用到的地方就可以不改
            // 拿到类型是Uniuni的channel
            /*String uniType = "Uniuni";
            List<Channel> uniChannelList = Optional.ofNullable(channels).orElse(Lists.newArrayList())
                    .stream().filter(channel -> channel.getServiceCode().equals(uniType)).collect(Collectors.toList());*/
            // 跟拿factory里一样改成用channelPlatFormId匹配
            List<Channel> uniChannelList = Optional.ofNullable(channels).orElse(Lists.newArrayList())
                    .stream().filter(channel -> channel.getChannelPlatformId().equals(ChannelPlatform.UNI_UNI.getValue())
                            || channel.getChannelPlatformId().equals(ChannelPlatform.SHIPPO.getValue())).collect(Collectors.toList());

            try (FileOutputStream fos = new FileOutputStream(zipFilePath);
                 ZipOutputStream zos = new ZipOutputStream(fos)) {
                for (Order order : orders) {
                    // 拿到当前order的serviceCode 是哪个承运商
                    /*String serviceCode = Optional.ofNullable(
                            Optional.ofNullable(uniChannelList).orElse(Lists.newArrayList()).stream()
                                    .filter(channel -> channel.getId().equals(order.getChannelId())).findFirst().orElse(new Channel()).getServiceCode()
                    ).orElse("");*/
                    // 跟拿factory里一样改成用channelPlatFormId匹配
                    Integer channelPlatFormId = Optional.ofNullable(
                            Optional.ofNullable(uniChannelList).orElse(Lists.newArrayList()).stream()
                                    .filter(channel -> channel.getId().equals(order.getChannelId())).findFirst().orElse(new Channel()).getChannelPlatformId()
                    ).orElse(-1);
                    /*if (serviceCode.equals(uniType)) {*/
                    if (channelPlatFormId.equals(ChannelPlatform.UNI_UNI.getValue())) {
                        // 承运商 创建运单没有返回pdf地址 这里单独调用下载面单接口
                        String trackingNumber = pdfMap.get(order.getId());
                        String uniResponse = uniUniRequest.printLabel(new UniPrintLabelReqDTO()
                                .setPackageId(trackingNumber).setLabelType(6).setLabelFormat("pdf").setType("base64"));
                        UniPrintPdtResponse uniPrintPdtResponse = JSONObject.parseObject(uniResponse, UniPrintPdtResponse.class);
                        String errorCode = Optional.ofNullable(uniPrintPdtResponse.getErrCode()).orElse("");
                        if (errorCode.equals("0")) {
                            List<UniPrintLabel> uniPrintLabelList = JSONObject.parseObject(uniPrintPdtResponse.getData(), new TypeReference<List<UniPrintLabel>>() {
                            });

                            // 测试返回多个base64
                            /*UniPrintLabel uniPrintLabel2 = new UniPrintLabel();
                            uniPrintLabel2.setLabelContent("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NzA4IDYyNSA1NzEgNTQ5IDY1OSA2MTUgODkwIDYxNiA1NDkgNjE2IDM1MSAzMDMgMzUxIDc1NCA0NTAgNDUwIDU1MSA1NzEgNDk1IDU3MSA1NTQgMzE2IDU3MSA1NzAgMjUwIDI1MCA1MjEgMjUwIDg3NiA1NzAgNTUwIDU3MSA1NzEgMzcwIDQ2OSAzNTMgNTcwIDUzMiA3MzYgNTMyIDUzMiA0NzIgNTcyIDMwMyA1NzIgNzU0IF0KIF0KL0NJRFRvR0lETWFwIDEyIDAgUgo+PgplbmRvYmoKOSAwIG9iago8PC9MZW5ndGggMzQ2Pj4Kc3RyZWFtCi9DSURJbml0IC9Qcm9jU2V0IGZpbmRyZXNvdXJjZSBiZWdpbgoxMiBkaWN0IGJlZ2luCmJlZ2luY21hcAovQ0lEU3lzdGVtSW5mbwo8PC9SZWdpc3RyeSAoQWRvYmUpCi9PcmRlcmluZyAoVUNTKQovU3VwcGxlbWVudCAwCj4+IGRlZgovQ01hcE5hbWUgL0Fkb2JlLUlkZW50aXR5LVVDUyBkZWYKL0NNYXBUeXBlIDIgZGVmCjEgYmVnaW5jb2Rlc3BhY2VyYW5nZQo8MDAwMD4gPEZGRkY+CmVuZGNvZGVzcGFjZXJhbmdlCjEgYmVnaW5iZnJhbmdlCjwwMDAwPiA8RkZGRj4gPDAwMDA+CmVuZGJmcmFuZ2UKZW5kY21hcApDTWFwTmFtZSBjdXJyZW50ZGljdCAvQ01hcCBkZWZpbmVyZXNvdXJjZSBwb3AKZW5kCmVuZAoKZW5kc3RyZWFtCmVuZG9iagoxMCAwIG9iago8PC9SZWdpc3RyeSAoQWRvYmUpCi9PcmRlcmluZyAoVUNTKQovU3VwcGxlbWVudCAwCj4+CmVuZG9iagoxMSAwIG9iago8PC9UeXBlIC9Gb250RGVzY3JpcHRvcgovRm9udE5hbWUgL01QREZBQStEZWphVnVTYW5zQ29uZGVuc2VkCiAvQ2FwSGVpZ2h0IDcyOQogL1hIZWlnaHQgNTQ3CiAvRm9udEJCb3ggWy05MTggLTQ2MyAxNjE0IDEyMzJdCiAvRmxhZ3MgNAogL0FzY2VudCA5MjgKIC9EZXNjZW50IC0yMzYKIC9MZWFkaW5nIDAKIC9JdGFsaWNBbmdsZSAwCiAvU3RlbVYgODcKIC9NaXNz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IDQxMSA3NTQgNDUwIDQ1MCA2MDcgNjQ0IDUzMyA2NDQgNjEwIDM5MSA2NDQgNjQxIDMwOCAzMDggNTk4IDMwOCA5MzggNjQxIDYxOCA2NDQgNjQ0IDQ0NCA1MzYgNDMwIDY0MSA1ODYgODMxIDU4MCA1ODYgNTIzIDY0MSAzMjkgNjQxIDc1NCBdCiBdCi9DSURUb0dJRE1hcCAxOSAwIFIKPj4KZW5kb2JqCjE2IDAgb2JqCjw8L0xlbmd0aCAzNDY+PgpzdHJlYW0KL0NJREluaXQgL1Byb2NTZXQgZmluZHJlc291cmNlIGJlZ2luCjEyIGRpY3QgYmVnaW4KYmVnaW5jbWFwCi9DSURTeXN0ZW1JbmZvCjw8L1JlZ2lzdHJ5IChBZG9iZSkKL09yZGVyaW5nIChVQ1MpCi9TdXBwbGVtZW50IDAKPj4gZGVmCi9DTWFwTmFtZSAvQWRvYmUtSWRlbnRpdHktVUNTIGRlZgovQ01hcFR5cGUgMiBkZWYKMSBiZWdpbmNvZGVzcGFjZXJhbmdlCjwwMDAwPiA8RkZGRj4KZW5kY29kZXNwYWNlcmFuZ2UKMSBiZWdpbmJmcmFuZ2UKPDAwMDA+IDxGRkZGPiA8MDAwMD4KZW5kYmZyYW5nZQplbmRjbWFwCkNNYXBOYW1lIGN1cnJlbnRkaWN0IC9DTWFwIGRlZmluZXJlc291cmNlIHBvcAplbmQKZW5kCgplbmRzdHJlYW0KZW5kb2JqCjE3IDAgb2JqCjw8L1JlZ2lzdHJ5IChBZG9iZSkKL09yZGVyaW5nIChVQ1MpCi9TdXBwbGVtZW50IDAKPj4KZW5kb2JqCjE4IDAgb2JqCjw8L1R5cGUgL0ZvbnREZXNjcmlwdG9yCi9Gb250TmFtZSAvTVBERkFBK0RlamFWdVNhbnNDb25kZW5zZWQtQm9sZAogL0NhcEhlaWdodCA3MjkKIC9YSGVpZ2h0IDU0NwogL0ZvbnRCQm94IFstOTYyIC00MTUgMTc3NyAxMTc1XQogL0ZsYWdzIDI2MjE0OAogL0FzY2VudCA5MjgKIC9EZXNjZW50IC0yMzYKIC9MZWFkaW5nIDAKIC9JdGFsaWNBbmdsZSAwCiAvU3RlbVYgMTY1CiAvTWlzc2luZ1dpZHRoIDU0MAogL1N0eWxlIDw8IC9QYW5vc2UgPCAw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b250IC9NUERGQUErRGVqYVZ1U2Fuc0NvbmRlbnNlZC1Cb2xkT2JsaXF1ZQovRW5jb2RpbmcgL0lkZW50aXR5LUgKL0Rlc2NlbmRhbnRGb250cyBbMjIgMCBSXQovVG9Vbmljb2RlIDIzIDAgUgo+PgplbmRvYmoKMjIgMCBvYmoKPDwvVHlwZSAvRm9udAovU3VidHlwZSAvQ0lERm9udFR5cGUyCi9CYXNlRm9udCAvTVBERkFBK0RlamFWdVNhbnNDb25kZW5zZWQtQm9sZE9ibGlxdWUKL0NJRFN5c3RlbUluZm8gMjQgMCBSCi9Gb250RGVzY3JpcHRvciAyNSAwIFIKL0RXIDU0MAovVyBbIDMyIFsgMzEzIDQxMCA0NjkgNjI2IDYyNiA5MDEgNzg1IDI3NSA0MTEgNDExIDQ3MCA3NTQgMzQyIDM3NCAzNDIgMzI5IF0KIDQ4IDU3IDYyNiA1OCA1OSAzNjAgNjAgNjIgNzU0IDYzIFsgNTIyIDkwMCA2OTYgNjg2IDY2MCA3NDcgNjE1IDYxNSA3MzggNzUzIDMzNCAzMzQgNjk3IDU3MyA4OTYgNzUzIDc2NSA2NTkgNzY1IDY5MyA2NDggNjE0IDczMCA2OTYgOTkzIDY5NCA2NTEgNjUyIDQxMSAzMjkgNDExIDc1NCA0NTAgNDUwIDYwNyA2NDQgNTMzIDY0NCA2MTAgMzkxIDY0NCA2NDEgMzA4IDMwOCA1OTggMzA4IDkzOCA2NDEgNjE4IDY0NCA2NDQgNDQ0IDUzNiA0MzAgNjQxIDU4NiA4MzEgNTgwIDU4NiA1MjMgNjQxIDMyOSA2NDEgNzU0IF0KIF0KL0NJRFRvR0lETWFwIDI2IDAgUgo+PgplbmRvYmoKMjMgMCBvYmoKPDwvTGVuZ3RoIDM0Nj4+CnN0cmVhbQovQ0lESW5pdCAvUHJvY1NldCBmaW5kcmVzb3VyY2UgYmVnaW4KMTIgZGljdCBiZWdpbgpiZWdpbmNtYXAKL0NJRFN5c3RlbUluZm8KPDwvUmVnaXN0cnkgKEFkb2JlKQovT3JkZXJpbmcgKFVDUykKL1N1cHBsZW1lbnQgMAo+PiBkZWYKL0NNYXBOYW1lIC9BZG9iZS1JZGVudGl0eS1VQ1MgZGVmCi9DTWFwVHlwZSAyIGRlZgoxIGJlZ2luY29kZXNw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MDAwMDI0MTQgMDAwMDAgbiAKMDAwMDAwMjQ4MyAwMDAwMCBuIAowMDAwMDAyNzkwIDAwMDAwIG4gCjAwMDAwMDMxNjYgMDAwMDAgbiAKMDAwMDAxNDc2OSAwMDAwMCBuIAowMDAwMDE0OTI3IDAwMDAwIG4gCjAwMDAwMTU0NzIgMDAwMDAgbiAKMDAwMDAxNTg2OCAwMDAwMCBuIAowMDAwMDE1OTM3IDAwMDAwIG4gCjAwMDAwMTYyNTUgMDAwMDAgbiAKMDAwMDAxNjYzMSAwMDAwMCBuIAowMDAwMDI4NzU1IDAwMDAwIG4gCjAwMDAwMjg5MjAgMDAwMDAgbiAKMDAwMDAyOTQ3MiAwMDAwMCBuIAowMDAwMDI5ODY4IDAwMDAwIG4gCjAwMDAwMjk5MzcgMDAwMDAgbiAKMDAwMDAzMDI2NCAwMDAwMCBuIAowMDAwMDMwNjQwIDAwMDAwIG4gCjAwMDAwNDI4ODQgMDAwMDAgbiAKMDAwMDA0NDQ1MyAwMDAwMCBuIAowMDAwMDQ0NzU0IDAwMDAwIG4gCjAwMDAwNDUwOTcgMDAwMDAgbiAKMDAwMDA0NTE4MSAwMDAwMCBuIAowMDAwMDQ1NjM5IDAwMDAwIG4gCjAwMDAwNDYxNjggMDAwMDAgbiAKMDAwMDA0NjQ2NCAwMDAwMCBuIAp0cmFpbGVyCjw8Ci9TaXplIDM2Ci9Sb290IDM1IDAgUgovSW5mbyAzNCAwIFIKL0lEIFs8OWEzMmMwMDVjMGI0OTU0ZjExNWFkZmI0YTRkYjUwODE+IDw5YTMyYzAwNWMwYjQ5NTRmMTE1YWRmYjRhNGRiNTA4MT5dCj4+CnN0YXJ0eHJlZgo0NjU4OAolJUVPRg==");
                            uniPrintLabelList.add(uniPrintLabel2);*/

                            // 合并字节数组为 PDF
                            Document document = new Document();
                            PdfCopy copy = new PdfCopy(document, Files.newOutputStream(Paths.get(trackingNumber + ".pdf")));
                            document.open();
                            for (UniPrintLabel uniPrintLabel : uniPrintLabelList) {
                                String labelContent = uniPrintLabel.getLabelContent();
                                // 将 Base64 解码为字节数组
                                byte[] bytes = Base64.getDecoder().decode(labelContent);
                                PdfReader reader = new PdfReader(new ByteArrayInputStream(bytes));
                                copy.addDocument(reader);
                                reader.close();
                            }
                            document.close();

                            // 将 PDF 压缩为 ZIP 并下载
                            ZipEntry entry = new ZipEntry(trackingNumber + ".pdf");
                            zos.putNextEntry(entry);

                            InputStream is = Files.newInputStream(Paths.get(trackingNumber + ".pdf"));
                            byte[] buffer = new byte[1024];
                            int len;
                            while ((len = is.read(buffer)) > 0) {
                                zos.write(buffer, 0, len);
                            }
                            zos.closeEntry();
                        }
                    } else {
                        String pdrUrl = order.getPdfUrl();
                        String trackingNumber = pdfMap.get(order.getId());
                        if (channelPlatFormId.equals(ChannelPlatform.SHIPPO.getValue())) {
                            String pattern = "origTrackNum=(\\d+)";
                            Pattern r = Pattern.compile(pattern);
                            Matcher m = r.matcher(trackingNumber);
                            if (m.find()) {
                                trackingNumber = m.group(1);
                                log.info("shippo提取到的 origTrackNum: [{}]", trackingNumber);
                            }
                        }
                        ResponseEntity<byte[]> response = restTemplate.exchange(
                                pdrUrl, HttpMethod.GET, null, byte[].class);
                        if (response.getStatusCode() == HttpStatus.OK) {
                            byte[] pdfBytes = response.getBody();
                            if (pdfBytes != null) {

                                ZipEntry entry = new ZipEntry(trackingNumber + ".pdf");
                                zos.putNextEntry(entry);
                                zos.write(pdfBytes);
                                zos.closeEntry();
                            }
                        }
                    }
                }
            } catch (IOException | DocumentException e) {
                throw new RuntimeException(e);
            } finally {
                // 流关闭
                // zos.close is.close() zos.close() fos.close()
            }
            String s = Global.DOWNLOAD_BY_FILE_NAME_API + fileName;
            //String s = "http://127.0.0.1:8080/app/static/download?fileName=" + fileName;
            return CommonResult.success(s);
        }

        return CommonResult.success();
    }

    @Override
    public CommonResult<String> releaseEarnest(OrderReleaseEarnestRequest request) {
        List<String> orderIds = request.getOrderIds();
        if (CollectionUtil.isNotEmpty(orderIds)) {
            // 一个个订单来
            for (String orderId : orderIds) {
                Order order = getById(orderId);

                if (order.getStatus() == OrderStatus.DRAFT.getValue()) {
                    log.info("该状态不可释放 {}", orderId);
                    continue;
                }

                if (order.getEarnestTime() != null) {
                    log.info("订单已经释放过了 {}", orderId);
                    continue;
                }

                BigDecimal earnest = order.getEarnest();
                if (earnest == null || BigDecimal.ZERO.compareTo(earnest) == 0) {
                    log.info("没有保证金可以释放 {}", orderId);
                    continue;
                }
                UserReleaseEarnestRequest userReleaseEarnestRequest = new UserReleaseEarnestRequest();
                userReleaseEarnestRequest.setEarnest(earnest);
                userReleaseEarnestRequest.setUserId(order.getUserId());
                userReleaseEarnestRequest.setOrderNo(order.getOrderNo());
                umsAdminService.releaseEarnest(userReleaseEarnestRequest);

                Order updateOrder = new Order();
                updateOrder.setEarnestTime(LocalDateTime.now());
                updateOrder.setId(Integer.parseInt(orderId));
                updateOrder.setEarnest(BigDecimal.ZERO);
                updateById(updateOrder);


            }


        }
        return CommonResult.success();
    }

    /**
     * 复制生成新订单
     * @param request
     * @return
     */
    @Override
    public CommonResult<String> copy(OrderCopyRequest request) {
        Integer userId = request.getUserId();
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<Order>()
                .eq(Order::getId, request.getOrderId())
                .eq(userId != null, Order::getUserId, request.getUserId())
                .orderByDesc(Order::getId);

        Order order = getOne(queryWrapper);
        if (order == null) {
            return CommonResult.success();
        }
        Order newOrder = new Order();
        BeanUtils.copyProperties(order, newOrder);
        //看订单表create_time字段是不是复制了
        newOrder.setOrderNo(order.getOrderNo() + "_" + UUID.randomUUID().toString().replace("-", "").substring(0, 4));
        newOrder.setStatus(OrderStatus.DRAFT.getValue());

        newOrder.setErrMsg(null);
        newOrder.setRate(null);
        newOrder.setEarnest(null);
        newOrder.setBatchNo(null);
        newOrder.setId(null);
        newOrder.setCreatedAt(null);

        //因为是复制成草稿 下单成功才有的字段不能复制过来
        newOrder.setObjectId(null);
        newOrder.setCreateTime(null);
        newOrder.setPlatformNo(null);
        newOrder.setPdfUrl(null);
        newOrder.setOriginFee(null);

        save(newOrder);

        Integer orderId = order.getId();
        List<OrderParcel> orderParcels = orderParcelService.list(new LambdaQueryWrapper<OrderParcel>().eq(OrderParcel::getOrderId, orderId));

        //货运标签时间updated_at不能有，因为草稿时还没有这个值SELECT id, updated_at FROM  `user_order_parcel`
        List<OrderParcel> newOrderParcels = orderParcels.stream().map(x -> {
            OrderParcel newOrderParcel = new OrderParcel();
            BeanUtils.copyProperties(x, newOrderParcel);
            newOrderParcel.setLabelUrl(null);
            newOrderParcel.setTrackingUrl(null);
            newOrderParcel.setTrackingNumber(null);
            newOrderParcel.setCreatedAt(null);
                 newOrderParcel.setUpdatedAt(null);
            newOrderParcel.setOrderId(newOrder.getId());
            newOrderParcel.setId(null);

            // 默认值
            if (StrUtil.isBlank(newOrderParcel.getPackageCode())) {
                newOrderParcel.setPackageCode("your_package");
            }
            if (cn.hutool.core.util.ObjectUtil.isNull(newOrderParcel.getPackageNum())) {
                newOrderParcel.setPackageNum(1);
            }

            return newOrderParcel;
        }).collect(Collectors.toList());

        orderParcelService.saveBatch(newOrderParcels);
        return CommonResult.success();
    }

    @Override
    public CommonResult<List<EstimateRateRequest>> uploadOrder(MultipartFile file) {
        List<ExcelOrder> excelOrders = Lists.newArrayList();
        String originalFilename = file.getOriginalFilename();
        try {
            excelOrders = EasyExcel.read(file.getInputStream(), ExcelOrder.class, new ExcelOrderListener())
                    .sheet().headRowNumber(1)
                    .doReadSync();
        } catch (Exception e) {
            StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
            log.error("批量导入订单 excel读取异常 {}: {}", stackTraceElement.getLineNumber(), e.getMessage(), e);
            Asserts.fail(e.getCause().getMessage());
        }
        UmsAdmin userInfo = AdminUserUtil.getUserInfo();
        List<GetOrdersResponse> getOrdersResponses = buildOrders(excelOrders);
        // 设置用户ID
        if (originalFilename.contains(".")) {
            originalFilename = originalFilename.substring(0, originalFilename.length() - 4);
        }
        Integer userId = userInfo.getId();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

        String finalOriginalFilename = originalFilename + "_" + LocalDateTime.now().format(formatter);
        getOrdersResponses.forEach(x -> {
            x.setBatchNo(finalOriginalFilename);
            x.setUserId(userId);
            x.setStatus(OrderStatus.DRAFT.getValue());

        });

        List<Order> orders = getOrdersResponses.stream().map(x -> {
            Order order = new Order();
            BeanUtils.copyProperties(x, order);
            order.setSellerId(userInfo.getSellerId());
            return order;
        }).collect(Collectors.toList());


        List<OrderParcel> allParcels = new ArrayList<>();
        for (int i = 0; i < orders.size(); i++) {
            Order order = orders.get(i);

            EstimateRateRequest estimateRateRequest = getEstimateRateRequest(order,null);
            checkOrderNo(estimateRateRequest);

            order.setOrderNo(estimateRateRequest.getOrderNO());
            save(order);

            GetOrdersResponse getOrdersResponse = getOrdersResponses.get(i);
            List<OrderParcel> parcels = getOrdersResponse.getParcels();
            AtomicInteger seriNum = new AtomicInteger();
            parcels.forEach(p -> {
                p.setUserId(userId);
                p.setOrderId(order.getId());
                p.setSeriNum(seriNum.getAndIncrement());
                allParcels.add(p);
                for (int j = 1; j < p.getPackageNum(); j++) {
                    OrderParcel orderParcel = new OrderParcel();
                    BeanUtils.copyProperties(p, orderParcel);
                    allParcels.add(orderParcel);
                }
            });
        }

        orderParcelService.saveBatch(allParcels);
        return CommonResult.success();
    }

    /**
     * 检查订单号是否重复
     * @param request
     */
    @Override
    public long checkOrderNo(EstimateRateRequest request) {
        long count = 0;
        String orderNO = request.getOrderNO();

        if (StringUtils.isBlank(orderNO)) {
            orderNO = CommonUtil.getOrderNo();
        } else {
            LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Order::getOrderNo, orderNO);
            Integer orderId = request.getOrderId();
            queryWrapper.ne(orderId != null, Order::getId, orderId);
             count = count(queryWrapper);
            if (count > 0) {

                // 更改为4位UUID
                //     DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
                //     orderNO = orderNO + "_"+ LocalDateTime.now().format(formatter);
               orderNO = orderNO + "_" + UUID.randomUUID().toString().replace("-", "").substring(0, 4);

            }
        }
        //平台生成的订单号
        request.setPlatformNo(CommonUtil.getOrderNo());

        request.setOrderNO(orderNO);
        return count;
    }

    /**
     * 不可重复
     * 1 是重复
     */
    @Override
    public Integer checkOrderNoNoRepeat(EstimateRateRequest request) {
        String orderNO = request.getOrderNO();

        if (StringUtils.isBlank(orderNO)) {
            orderNO = CommonUtil.getOrderNo();
        } else {
            LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Order::getOrderNo, orderNO);
            queryWrapper.ne(request.getOrderId() != null, Order::getId, request.getOrderId());
            List<Order> list = list(queryWrapper);
            if (list.size() > 0) {
                //平台生成的订单号
                request.setPlatformNo(CommonUtil.getOrderNo());
                String objectId = list.get(0).getObjectId();
                request.setOrderNO(orderNO);
                request.setObjectId(objectId);
                return 1;
                //throw new RuntimeException("订单"+orderNO+"已创建请不要重复提交");

            }
        }
        //平台生成的订单号
        request.setPlatformNo(CommonUtil.getOrderNo());

        request.setOrderNO(orderNO);

        return 0;
    }

    @Override
    public CommonResult<GetOrdersResponse> detail(OrderDetailRequest request) {
        Integer userId = request.getUserId();

        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(request.getOrderId() != null, Order::getId, request.getOrderId());
        wrapper.eq(userId != null, Order::getUserId, userId);
        wrapper.orderByDesc(Order::getId);
        Order order = getOne(wrapper);
        if (order == null) {
            return CommonResult.failed("Permission denied");
        }

        Integer orderId = order.getId();
        Map<Integer, List<OrderParcel>> orderParcelsMap = orderParcelService.list(new LambdaQueryWrapper<OrderParcel>()
                .eq(OrderParcel::getOrderId, orderId)).stream().collect(Collectors.groupingBy(OrderParcel::getOrderId));
        Map<Integer, Channel> channelMap = channelService.list(new LambdaQueryWrapper<Channel>()
                        .eq(Channel::getId, order.getChannelId()))
                .stream().collect(Collectors.toMap(Channel::getId, Function.identity()));

        Map<Integer, ChannelCarrier> channelCarrierMap = channelCarrierService.list(new LambdaQueryWrapper<>())
                .stream().collect(Collectors.toMap(ChannelCarrier::getId, Function.identity()));
        GetOrdersResponse getOrdersResponse = new GetOrdersResponse();
        BeanUtils.copyProperties(order, getOrdersResponse);
        List<OrderParcel> parcels = orderParcelsMap.get(order.getId());

        if (OrderStatus.DRAFT.getValue() == order.getStatus()) {
            parcels = getDraftParcels(parcels);
        }
        getOrdersResponse.setParcels(parcels);
        Channel channel = channelMap.get(order.getChannelId());
        if (channel != null) {
            getOrdersResponse.setServiceName(channel.getChannelName());
            ChannelCarrier channelCarrier = channelCarrierMap.get(channel.getChannelCarrierId());
            if (channelCarrier != null) {
                getOrdersResponse.setCarrierName(channelCarrier.getChannelCarrierName());

            }
        }
        //两个国家不相等的查清关
        if (!getOrdersResponse.getFromCountryCode().equalsIgnoreCase(getOrdersResponse.getToCountryCode())){

            // 清关信息 只有两个国家code不同才查询
            UserOrderInter userOrderInter = userOrderInterService.lambdaQuery()
                    .eq(UserOrderInter::getOrderId, orderId)

                    .one();
            getOrdersResponse.setUserOrderInter(userOrderInter);
        }
        return CommonResult.success(getOrdersResponse);
    }

    @Override
    public CommonResult<EstimateRateOrderResponse> draft(EstimateRateRequest request) {
        EstimateRateOrderResponse estimateRateOrderResponse = new EstimateRateOrderResponse();
        Integer userId = AdminUserUtil.getUserId();

        //根据渠道id 获取渠道列表
        List<UserChannelVO> channels = channelService.getOnChannels(userId, request.getServiceCode(), null);
        if (CollectionUtil.isEmpty(channels)) {
            return CommonResult.failed("Permission denied");
        }
        // 保存到草稿
        if (request.getOrderId() != null) {
            Order order = getById(request.getOrderId());
            if (OrderStatus.DRAFT.getValue() != order.getStatus()) {
                return CommonResult.failed("请确认订单状态为草稿");
            }
        }
        Order order = saveOrder(request, userId);
        estimateRateOrderResponse.setOrderId(order.getId());
        return CommonResult.success(estimateRateOrderResponse);
    }

    /**
     * 生成面单
     * @param estimateRateRequest
     * @return
     */
    @Override
    public CommonResult<String> createLabel(EstimateRateRequest estimateRateRequest) {
        Integer userId = AdminUserUtil.getUserId();

        estimateRateRequest.setIsTest(false);
        Integer serviceId = estimateRateRequest.getChannelId();
        Channel channel = channelService.getById(serviceId);
        String serviceCode = channel.getChannelCode();
        if (channel == null) {
            return CommonResult.failed("Permission denied");
        }
        estimateRateRequest.setServiceCode(serviceCode);


        // 判断订单是否能下单
        Integer orderId = estimateRateRequest.getOrderId();
        if (orderId != null) {
            Order order = getOne(new LambdaQueryWrapper<Order>().eq(Order::getId, orderId));
            if (StringUtils.isNotBlank(order.getPdfUrl())) {
                return CommonResult.failed("该订单已下单成功 请返回订单列表查看,退加草稿的原订单需复制生成新订单再重新下单");
            }
        }

        // 获取用户权限
        List<UserChannel> userChannels = userChannelService.list(new LambdaQueryWrapper<UserChannel>()
                .eq(UserChannel::getUserId, userId)
        );
        if (CollectionUtil.isEmpty(userChannels)) {
            return CommonResult.failed("user get no channel");
        }
        ChannelCarrier channelCarrier = channelCarrierService.getOne(new LambdaQueryWrapper<ChannelCarrier>()
                .eq(ChannelCarrier::getId, channel.getChannelCarrierId()));
        estimateRateRequest.setCarrierCode(channelCarrier.getChannelCarrierCode());

        UserChannel userChannel = userChannels.stream().filter(x -> {
            return x.getChannelId() == channel.getId().intValue();
        }).findFirst().get();
        UserChannelVO userChannelVO = new UserChannelVO();
        BeanUtils.copyProperties(userChannel, userChannelVO);
        userChannelVO.setChannel(channel);
        estimateRateRequest.setUserChannelVO(userChannelVO);
        BaseShipService baseShipService = shipFactory.getBaseShipService(channel);

        checkOrderNo(estimateRateRequest);
        MathUtil.fmtWeight2(estimateRateRequest);
        //下单
        CommonResult label = baseShipService.createLabel(estimateRateRequest, userId);

        String msg = label.getMessage();
        if (!label.isSucess()) {
            return CommonResult.failed(msg);
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult<String> batch(List<BatchCreateLabelOrderRequest> request,Integer userId) {
        List<Integer> orderIds = request.stream().map(BatchCreateLabelOrderRequest::getOrderId).collect(Collectors.toList());
        //查询订单祥情
        List<Order> orderList = lambdaQuery().eq(Order::getStatus, OrderStatus.DRAFT).in(Order::getId, orderIds).list();
        if (CollectionUtil.isNotEmpty(orderList)) {
            //加入批量下单队伍中
            addTaskQuee(request, userId, orderIds);
        }else {
            return CommonResult.failed("订单号没有在草稿状态的");

        }
        return CommonResult.success();
    }

    /**
     *  加入批量下单队伍中
     * @param request
     * @param userId
     * @param orderIds
     */
    @Transactional(rollbackFor = Exception.class)
    void addTaskQuee(List<BatchCreateLabelOrderRequest> request, Integer userId, List<Integer> orderIds) {
        //修改同批次的订单为下单中
        boolean isFlag = lambdaUpdate()
                .set(Order::getStatus, OrderStatus.ORDER_PLAY)
                .eq(Order::getStatus, OrderStatus.DRAFT)
                .in(Order::getId, orderIds)
                .update();
        if (isFlag) {
            //插入数据
            iOrderTaskService.insertTask(request, userId);
        }
    }


    @Override
    public CommonResult<String> batchOld(BatchCreateLabelOrderRequest request) {
        //校验是否拥有渠道权限
        List<Order> orderList = lambdaQuery().eq(Order::getStatus, OrderStatus.DRAFT).in(Order::getId, request.getOrderIds()).list();
        if (CollectionUtil.isEmpty(orderList)) {
            return CommonResult.failed("Permission denied");
        }
        for (Order order : orderList) {
            List<UserChannelVO> channels = channelService.getOnChannels(order.getUserId(), null, request.getChannelId());
            if (CollectionUtil.isEmpty(channels)) {
                return CommonResult.failed("Permission denied");
            }
        }
        //修改同批次的订单为下单中
        List<Order> orders = lambdaQuery()
                .eq(Order::getStatus, OrderStatus.DRAFT)
                //.eq(Order::getUserId, request.getUserId())
                .in(Order::getId, request.getOrderIds())
                .list();
        if (CollectionUtil.isNotEmpty(orders)) {
            //老版本-新增批量下单任务
            addTaskQueeOld(request);
        }
        return CommonResult.success();
    }

    /**
     * 老版本-新增批量下单任务
     * @param request
     */
    @Transactional(rollbackFor = Exception.class)
     void addTaskQueeOld(BatchCreateLabelOrderRequest request) {
        boolean isFlag = lambdaUpdate()
                .set(Order::getStatus, OrderStatus.ORDER_PLAY)
                .eq(Order::getStatus, OrderStatus.DRAFT)
                .in(Order::getId, request.getOrderIds())
                .update();
        if (isFlag) {
            //插入数据
            iOrderTaskService.insert(request);
        }
    }

    @Override
    public EstimateRateRequest getEstimateRateRequest(Integer orderId) {
        return getEstimateRateRequest(getById(orderId),null);
    }

    @Override
    public void fillParcel(Integer orderId, Channel channel, EstimateRateRequest estimateRateRequest) {
        fillParcel(getById(orderId), channel, estimateRateRequest);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<String> releaseDeposit(OrderReleaseEarnestRequest request) {
        //查询条件 保证金释放时间为空，状态不为草稿，保证金金额不为0
        List<Order> orders = lambdaQuery()
                .in(Order::getId, request.getOrderIds())
                .isNull(Order::getEarnestTime)
                .ne(Order::getStatus, OrderStatus.DRAFT)
                .ne(Order::getEarnest, new BigDecimal("0"))
                .list();
        if (CollectionUtil.isNotEmpty(orders)) {
            List<UserReleaseEarnestRequest> st = new ArrayList<>(orders.size());
            for (Order order : orders) {
                UserReleaseEarnestRequest userReleaseEarnestRequest = new UserReleaseEarnestRequest();
                userReleaseEarnestRequest.setEarnest(order.getEarnest());
                userReleaseEarnestRequest.setUserId(order.getUserId());
                userReleaseEarnestRequest.setOrderNo(order.getOrderNo());
                st.add(userReleaseEarnestRequest);
            }
            boolean isFlag = lambdaUpdate()
                    .set(Order::getEarnestTime, LocalDateTime.now())
                    .set(Order::getEarnest, new BigDecimal("0"))
                    .in(Order::getId, orders.stream().map(Order::getId).collect(Collectors.toList()))
                    .isNull(Order::getEarnestTime)
                    .ne(Order::getStatus, OrderStatus.DRAFT)
                    .ne(Order::getEarnest, new BigDecimal("0"))
                    .update();
            if (isFlag) {
                umsAdminService.releaseDeposit(st);
            }
        }
        return CommonResult.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<GetOrdersResponse> cancelAudit(OrderCancelAuditRequest request) {
        //查询订单
        List<Order> orders = lambdaQuery()
                .eq(Order::getStatus, OrderStatus.CANCEL_ING)
                .in(Order::getId, request.getOrderIds())
                .list();
        if (CollectionUtil.isNotEmpty(orders)) {
            List<Order> orderList = new ArrayList<>(orders.size());
            for (Order order : orders) {
                BigDecimal earnest = order.getEarnest();
                order.setStatus(OrderStatus.CANCEL.getValue());
                order.setAuditorBy(AdminUserUtil.getUserInfo().getUsername());
                order.setEarnestTime(LocalDateTime.now());
                order.setAuditorTime(LocalDateTime.now());
                order.setEarnest(new BigDecimal("0"));
                orderList.add(order);
                //查询该笔订单是否生成支付记录
                List<BalanceLog> balanceLogs = balanceLogService.lambdaQuery()
                        .eq(BalanceLog::getOrderNo, order.getOrderNo())
                        .eq(BalanceLog::getType, BalanceLogType.CONSUME)
                        .list();
                if (CollectionUtil.isNotEmpty(balanceLogs)) {
                    //订单取消释放保证金
                    umsAdminService.releaseDepositByCancelAudit(order.getUserId(), order.getRate(), earnest, order.getOrderNo());
                }
            }
            updateBatchById(orderList);
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult<GetOrdersResponse> reject(OrderCancelAuditRequest request) {
        List<Order> orders = lambdaQuery()
                .eq(Order::getStatus, OrderStatus.CANCEL_ING)
                .in(Order::getId, request.getOrderIds())
                .list();
        if (CollectionUtil.isNotEmpty(orders)) {
            lambdaUpdate()
                    .eq(Order::getStatus, OrderStatus.CANCEL_ING)
                    .in(Order::getId, orders.stream().map(Order::getId).collect(Collectors.toList()))
                    .set(Order::getStatus, OrderStatus.CANCEL_REJECT)
                    .set(Order::getAuditorTime, LocalDateTime.now())
                    .set(Order::getAuditorBy, AdminUserUtil.getUserInfo().getUsername())
                    .set(Order::getAuditInfo, request.getAuditInfo())
                    .update();
        }
        return CommonResult.success();
    }

    @Override
    public BigDecimal sumRefundAmountByUserId(Integer id) {
        return ObjectUtils.isNotEmpty(id) ? orderMapper.sumRefundAmountByUserId(id) : new BigDecimal("0");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult orderBilled(List<BilledDto> dtos) {
        UmsAdmin userInfo = AdminUserUtil.getUserInfo();
        if (!userInfo.isAdmin()) {
            return CommonResult.failed("function only for admin");
        }
        //查询对应订单是否存在
        List<Order> orders = lambdaQuery()
                .select(Order::getId, Order::getOrderNo, Order::getUserId, Order::getBilled)
                .in(Order::getId, dtos.stream().map(BilledDto::getOrderId).collect(Collectors.toList()))
                .in(Order::getStatus, OrderStatus.CANCEL_ING, OrderStatus.RECENT)
                .list();
        if (CollectionUtil.isEmpty(orders) || dtos.size() != orders.size()) {
            return CommonResult.failed("orders not all in canceling or recent");
        }
        Map<Integer, BilledDto> billedMap = dtos.stream()
                .collect(Collectors.toMap(BilledDto::getOrderId, dto -> dto));
        //补扣
        List<BalanceLog> balanceLogs = new ArrayList<>(orders.size());
        for (Order order : orders) {
            BilledDto dto = billedMap.get(order.getId());
            BigDecimal amount = 1 == dto.getChangeType() ? dto.getAmount().multiply(new BigDecimal("-1")) : dto.getAmount();
            lambdaUpdate().setSql("billed = billed +" + amount).eq(Order::getId, order.getId()).update();
            //查询对应的用户信息
            UmsAdmin user = umsAdminService.getById(order.getUserId());
            BigDecimal balance = user.getBalance();
            umsAdminService.lambdaUpdate()
                    .setSql("balance = balance + " + amount)
                    .eq(UmsAdmin::getId, user.getId())
                    .update();
            //生成对应补扣记录
            BalanceLog bl = new BalanceLog();
            bl.setUserId(order.getUserId());
            bl.setChangeValue(amount);
            bl.setAfterValue(balance.add(amount));
            bl.setType(BalanceLogType.BILLED);
            bl.setBalanceType(BalanceType.BALANCE);
            bl.setOrderNo(order.getOrderNo());
            bl.setSellerId(user.getSellerId());
            bl.setRemark("账单补扣");
            balanceLogs.add(bl);
        }
        balanceLogService.saveBatch(balanceLogs);
        return CommonResult.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult uploadBilled(MultipartFile file) {
        List<ExcelBilled> billeds = null;
        try {
            billeds = EasyExcel.read(file.getInputStream(), ExcelBilled.class, new ExcelBilledListener())
                    .sheet().headRowNumber(1)
                    .doReadSync();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (CollectionUtil.isEmpty(billeds)) {
            throw new RuntimeException("未解析出对应数据");
        }
        List<String> orderNos = new ArrayList<>(billeds.size());
        List<BalanceLog> balanceLogs = new ArrayList<>(billeds.size());
        //遍历集合
        for (ExcelBilled billed : billeds) {
            //判断是否有差价
            //实际支付金额
            BigDecimal actualCost = new BigDecimal(billed.getActualCost());
            //订单金额
            BigDecimal rateAmount = new BigDecimal(billed.getRateAmount());
            if (rateAmount.compareTo(actualCost) != 0) {
                //差价
                BigDecimal subtract = actualCost.subtract(rateAmount);
                //操作对应的订单
                List<OrderParcel> orderParcels = orderParcelService.lambdaQuery().eq(OrderParcel::getTrackingNumber, billed.getTrackNumber()).list();
                if (CollectionUtil.isNotEmpty(orderParcels)) {
                    Order order = getById(orderParcels.get(0).getOrderId());
                    lambdaUpdate().setSql("billed = billed +" + subtract).eq(Order::getId, order.getId()).update();
                    //操作对应订单的用户余额
                    UmsAdmin user = umsAdminService.getById(order.getUserId());
                    BigDecimal balance = user.getBalance();
                    umsAdminService.lambdaUpdate()
                            .setSql("balance = balance + " + subtract)
                            .eq(UmsAdmin::getId, user.getId())
                            .update();
                    //生成对应余额变动记录
                    BalanceLog bl = new BalanceLog();
                    bl.setUserId(order.getUserId());
                    bl.setChangeValue(subtract);
                    bl.setAfterValue(balance.add(subtract));
                    bl.setType(BalanceLogType.BILLED);
                    bl.setBalanceType(BalanceType.BALANCE);
                    bl.setOrderNo(order.getOrderNo());
                    bl.setSellerId(user.getSellerId());
                    String remark = StringUtils.isNotBlank(billed.getReason()) ? billed.getReason() : "账单补扣";
                    bl.setRemark(remark);
                    balanceLogService.save(bl);
                } else {
                    orderNos.add(billed.getTrackNumber());
                }
                //balanceLogService.saveBatch(balanceLogs);
            }
        }
        return CommonResult.success(JSON.toJSONString(orderNos));
    }

    /**
     * 保存草稿
     * @param request
     * @param userId
     * @return
     */
    @NotNull
    private Order saveOrder(EstimateRateRequest request, Integer userId) {
        Order order = transferOrder(request);
        saveOrUpdate(order);

        Integer orderId = order.getId();
        Order dbOrder = getById(orderId);
        Integer dbUserId = dbOrder.getUserId();
        List<EstimateRateRequest.Parcel> parcels = request.getParcels();

        List<OrderParcel> orderParcels = ParcelUtil.getOrderParcels(parcels, orderId, dbUserId);

        // 删除之前的订单
        orderParcelService.remove(new LambdaUpdateWrapper<OrderParcel>().eq(OrderParcel::getOrderId, orderId));
        // 入库
        orderParcelService.saveBatch(orderParcels);

        // saveOrUpdate
        EstimateRateRequest.LabelExtra extra = Optional.ofNullable(request.getExtra()).orElse(new EstimateRateRequest.LabelExtra());

        //两个国家不相等的查清关
        if (!order.getFromCountryCode().equalsIgnoreCase(order.getToCountryCode())) {
            //保存清关单
            // 一个订单 只有一条 更新 两个国家code不同才保存 或更新
            UserOrderInter orderInter = userOrderInterService.lambdaQuery()
                    .eq(UserOrderInter::getOrderId, orderId).select(UserOrderInter::getId).one();
            if (orderInter == null) {
                orderInter = new UserOrderInter();
            }
            orderInter.setUserId(dbUserId);
            orderInter.setOrderId(orderId);
            orderInter.setEinNumber(extra.getEinNumber());
            orderInter.setNonDeliveryOption(extra.getNonDeliveryOption());
            orderInter.setCertifySigner(extra.getCertifySigner());
            orderInter.setCountryOfOrigin(extra.getCountryOfOrigin());
            orderInter.setCustomsDeclaration(extra.getCustomsDeclaration());
            orderInter.setDescription(extra.getDescription());
            orderInter.setContentsType(extra.getContentsType());
            orderInter.setQuantity(extra.getQuantity());
            orderInter.setQuantityUnit(extra.getQuantityUnit());
            orderInter.setType(extra.getType());
            orderInter.setWeight(extra.getWeight());
            orderInter.setWeightUnit(extra.getWeightUnit());
//               orderInter .setContactPhone(extra.getContactPhone());
//               orderInter .setCarrierServiceCode(extra.getCarrierServiceCode());
//               orderInter .setRemark(extra.getRemark());
//               orderInter .setScheduleB(extra.getScheduleB());
//               orderInter .setLabelSize(extra.getLabelSize());
//               orderInter .setProductTemplate(extra.getProductTemplate());


            userOrderInterService.saveOrUpdate(orderInter);
        }


        return order;
    }


    private static List<OrderParcel> getDraftParcels(List<OrderParcel> orderParcels) {
        List<OrderParcel> newOrderParcels = new ArrayList<>();
        Set<Integer> seriNums = new HashSet<>();
        for (OrderParcel orderParcel : orderParcels) {
            if (!seriNums.contains(orderParcel.getSeriNum())) {
                seriNums.add(orderParcel.getSeriNum());
                newOrderParcels.add(orderParcel);
            }
        }
        return newOrderParcels;
    }


    /**
     * 设置包裹
     * @param order
     * @param channel
     * @param estimateRateRequest
     */
    private void fillParcel(Order order, Channel channel, EstimateRateRequest estimateRateRequest) {
        List<OrderParcel> orderParcels = orderParcelService.list(new LambdaQueryWrapper<OrderParcel>().eq(OrderParcel::getOrderId, order.getId()));
        Integer channelPlatformId = channel.getChannelPlatformId();
        List<EstimateRateRequest.Parcel> parcels = getParcels(orderParcels, channelPlatformId);
        estimateRateRequest.setParcels(parcels);
    }

    /**
     * 没有平台2的包裹
     * @param order
     * @param
     * @param estimateRateRequest
     */
    private void fillNomalParcel(Order order,  EstimateRateRequest estimateRateRequest) {
        List<OrderParcel> orderParcels = orderParcelService.list(new LambdaQueryWrapper<OrderParcel>().eq(OrderParcel::getOrderId, order.getId()));

        List<EstimateRateRequest.Parcel> parcels;
        //Ezeeship支持包裹数量2，其他的只能分成2个包裹
        parcels = orderParcels.stream().map(x -> {
            EstimateRateRequest.Parcel parcel = new EstimateRateRequest.Parcel();
            BeanUtils.copyProperties(x, parcel);
            return parcel;

        }).collect(Collectors.toList());
        estimateRateRequest.setParcels(parcels);
    }
    private void fillezParcel(Order order,  EstimateRateRequest estimateRateRequest) {
        List<OrderParcel> orderParcels = orderParcelService.list(new LambdaQueryWrapper<OrderParcel>().eq(OrderParcel::getOrderId, order.getId()));
        List<OrderParcel> newOrderParcels = new ArrayList<>();
        List<EstimateRateRequest.Parcel> parcels;
        //Ezeeship支持包裹数量2，其他的只能分成2个包裹
        Set<Integer> seriNums = new HashSet<>();
        for (OrderParcel orderParcel : orderParcels) {
            if (!seriNums.contains(orderParcel.getSeriNum())) {
                seriNums.add(orderParcel.getSeriNum());
                newOrderParcels.add(orderParcel);
            }
        }
        parcels = newOrderParcels.stream().map(x -> {
            EstimateRateRequest.Parcel parcel = new EstimateRateRequest.Parcel();
            BeanUtils.copyProperties(x, parcel);
            return parcel;

        }).collect(Collectors.toList());
        estimateRateRequest.setParcels(parcels);
    }

    @NotNull
    private static List<EstimateRateRequest.Parcel> getParcels(List<OrderParcel> orderParcels, Integer channelPlatformId) {
        List<OrderParcel> newOrderParcels = new ArrayList<>();
        List<EstimateRateRequest.Parcel> parcels;
        //Ezeeship支持包裹数量2，其他的只能分成2个包裹
        if (ChannelPlatform.EZEE_SHIP.getValue() == channelPlatformId) {
            Set<Integer> seriNums = new HashSet<>();
            for (OrderParcel orderParcel : orderParcels) {
                if (!seriNums.contains(orderParcel.getSeriNum())) {
                    seriNums.add(orderParcel.getSeriNum());
                    newOrderParcels.add(orderParcel);
                }
            }
            parcels = newOrderParcels.stream().map(x -> {
                EstimateRateRequest.Parcel parcel = new EstimateRateRequest.Parcel();
                BeanUtils.copyProperties(x, parcel);
                return parcel;

            }).collect(Collectors.toList());
        } else {
            parcels = orderParcels.stream().map(x -> {
                EstimateRateRequest.Parcel parcel = new EstimateRateRequest.Parcel();
                BeanUtils.copyProperties(x, parcel);
                return parcel;

            }).collect(Collectors.toList());
        }

        return parcels;
    }

    @NotNull
    private static EstimateRateRequest getEstimateRateRequest(Order order,UserOrderInter userOrderInter) {
        EstimateRateRequest estimateRateRequest = new EstimateRateRequest();
        BeanUtils.copyProperties(order, estimateRateRequest);
        estimateRateRequest.setIsTest(false);
        EstimateRateRequest.Address from = new EstimateRateRequest.Address();
        from.setCity(order.getFromCity());
        from.setEmail(order.getFromEmail());
        from.setCompany(order.getFromCompany());
        from.setPhone(order.getFromPhone());
        from.setAddressLine1(order.getFromAddressLine1());
        from.setAddressLine2(order.getFromAddressLine2());
        from.setCountryCode(order.getFromCountryCode());
        from.setZipCode(order.getFromZipCode());
        from.setPersonName(order.getFromPersonName());
        from.setStateCode(order.getFromStateCode());
        estimateRateRequest.setFrom(from);

        EstimateRateRequest.Address to = new EstimateRateRequest.Address();
        to.setCity(order.getToCity());
        to.setEmail(order.getToEmail());
        to.setCompany(order.getToCompany());
        to.setPhone(order.getToPhone());
        to.setAddressLine1(order.getToAddressLine1());
        to.setAddressLine2(order.getToAddressLine2());
        to.setCountryCode(order.getToCountryCode());
        to.setZipCode(order.getToZipCode());
        to.setPersonName(order.getToPersonName());
        to.setStateCode(order.getToStateCode());
        estimateRateRequest.setTo(to);

        estimateRateRequest.setOrderNO(order.getOrderNo());
        estimateRateRequest.setOrderId(order.getId());

        EstimateRateRequest.LabelExtra extra = new EstimateRateRequest.LabelExtra();
        extra.setReference(order.getReference());
        extra.setReference2(order.getReference2());


        if (userOrderInter!=null){

            extra.setQuantity(userOrderInter.getQuantity());
            extra.setQuantityUnit(userOrderInter.getQuantityUnit());
            extra.setWeight(userOrderInter.getWeight());
            extra.setWeightUnit(userOrderInter.getWeightUnit());
            //海关申报价值
            extra.setCustomsDeclaration(userOrderInter.getCustomsDeclaration());
            extra.setCountryOfOrigin(extra.getCountryOfOrigin());
            //private String tariffNumber;
            extra.setDescription(extra.getDescription());




        }




        estimateRateRequest.setExtra(extra);
        return estimateRateRequest;
    }


    private EstimateRateRequest.Parcel buildParcel(ExcelOrder x) {
        EstimateRateRequest.Parcel parcel = new EstimateRateRequest.Parcel();
        parcel.setLength(x.getDimensionsL().toString());
        parcel.setHeight(x.getDimensionsH().toString());
        parcel.setWidth(x.getDimensionsW().toString());

        parcel.setWeight(x.getWeightLbKg().toString());
        parcel.setMassUnit("lb");
        parcel.setDistanceUnit("in");
        parcel.setPackageCode("your_package");
        return parcel;
    }

    private EstimateRateRequest buildEstimateRateRequest(ExcelOrder x) {
        EstimateRateRequest req = new EstimateRateRequest();

        req.setOrderNO(x.getOrderNo());

        req.setParcels(new ArrayList<>());

        req.setFrom((new EstimateRateRequest.Address())
                .setPersonName(x.getSender())
                .setPhone(x.getSenderTelephone())
                .setCompany(x.getSenderCompany())
                .setAddressLine1(x.getSenderAddress1())
                .setAddressLine2(x.getSenderAddress2())
                .setCity(x.getSenderCity())
                .setState(x.getSenderState())
                .setStateCode(x.getSenderState())
                .setZipCode(x.getSenderZipcode())
                .setCountryCode(x.getSenderCountry()));

        req.setTo((new EstimateRateRequest.Address())
                .setPersonName(x.getRecipient())
                .setPhone(x.getRecipientTelephone())
                .setCompany(x.getRecipientCompany())
                .setAddressLine1(x.getRecipientAddress1())
                .setAddressLine2(x.getRecipientAddress2())
                .setCity(x.getRecipientCity())
                .setState(x.getRecipientState())
                .setStateCode(x.getRecipientState())
                .setZipCode(x.getRecipientZipcode())
                .setCountryCode(x.getRecipientCountry()));


        return req;
    }

    @Override
    public List<UserSumAmountDto> getTopRateByUserDate(List<Integer> orderNormalStatus) {
        List<UserSumAmountDto> topAmountByUserDate = orderMapper.getTopAmountByUserDate(orderNormalStatus);
        if (CollUtil.isNotEmpty(topAmountByUserDate)) {
            List<UmsAdmin> dbUserInfos = umsAdminService.list(new LambdaQueryWrapper<UmsAdmin>()
                    .in(UmsAdmin::getId, topAmountByUserDate.stream().map(UserSumAmountDto::getUserId).collect(Collectors.toList()))
                    .select(UmsAdmin::getId, UmsAdmin::getRealName, UmsAdmin::getUsername, UmsAdmin::getEmail));
            return topAmountByUserDate.stream().peek(item -> {
                UmsAdmin umsAdmin = dbUserInfos.stream().filter(user -> user.getId().equals(item.getUserId().intValue())).findFirst().orElse(new UmsAdmin());
                item.setRealName(StrUtil.isNotBlank(umsAdmin.getRealName()) ? umsAdmin.getRealName() : umsAdmin.getUsername());
                item.setEmail(umsAdmin.getEmail());
            }).collect(Collectors.toList());
        }
        return topAmountByUserDate;
        /*List<UserSumAmountDto> userSumAmounts = orderMapper.getTopAmountByUserDate(orderNormalStatus);
        List<UserSumAmountDto> sumOrderNum = getSumOrderNum(userSumAmounts.stream().map(UserSumAmountDto::getUserId).collect(Collectors.toList()), orderNormalStatus);
        return userSumAmounts.stream().peek(userSumAmountDto -> {
            UserSumAmountDto userOrderInfo = sumOrderNum.stream().filter(userOrder -> userOrder.getUserId().equals(userSumAmountDto.getUserId())).findFirst().orElse(null);
            userSumAmountDto.setOrderNum(Optional.ofNullable(userOrderInfo).isPresent() ? userOrderInfo.getOrderNum() : 0);
        }).collect(Collectors.toList());*/
    }

    /*private List<UserSumAmountDto> getSumOrderNum(List<Long> userIds, List<Integer> orderNormalStatus) {
        return orderMapper.getOrderNumByUsers(orderNormalStatus, userIds);
    }*/

    @Override
    public List<UserSumAmountDto> getAmountNum(Integer userId, List<Integer> orderNormalStatus) {
        List<UserSumAmountDto> orderAmountSum = orderMapper.getOrderAmountSum(userId, orderNormalStatus);
        if (CollUtil.isNotEmpty(orderAmountSum)) {
            UmsAdmin one = umsAdminService.getOne(new LambdaQueryWrapper<UmsAdmin>().eq(UmsAdmin::getId, userId)
                    .select(UmsAdmin::getId, UmsAdmin::getRealName, UmsAdmin::getUsername, UmsAdmin::getEmail));
            return orderAmountSum.stream().peek(item -> {
                item.setRealName(StrUtil.isNotBlank(one.getRealName()) ? one.getRealName() : one.getUsername());
                item.setEmail(one.getEmail());
            }).collect(Collectors.toList());
        }
        return orderAmountSum;
    }

    @Override
    public List<UserSumAmountDto> getUserAmountNum(Integer sellerId, List<Integer> orderNormalStatus) {
        List<UserSumAmountDto> userAmountNum = orderMapper.getUserAmountNum(sellerId, orderNormalStatus);
        if (CollUtil.isNotEmpty(userAmountNum)) {
            List<UmsAdmin> dbUserInfos = umsAdminService.list(new LambdaQueryWrapper<UmsAdmin>()
                    .in(UmsAdmin::getId, userAmountNum.stream().map(UserSumAmountDto::getUserId).collect(Collectors.toList()))
                    .select(UmsAdmin::getId, UmsAdmin::getRealName, UmsAdmin::getUsername, UmsAdmin::getEmail));
            return userAmountNum.stream().peek(item -> {
                UmsAdmin umsAdmin = dbUserInfos.stream().filter(user -> user.getId().equals(item.getUserId().intValue())).findFirst().orElse(new UmsAdmin());
                item.setRealName(StrUtil.isNotBlank(umsAdmin.getRealName()) ? umsAdmin.getRealName() : umsAdmin.getUsername());
                item.setEmail(umsAdmin.getEmail());
            }).collect(Collectors.toList());
        }
        return userAmountNum;
    }
    @Override
    public List<DailyOrderAmountVO> getDailyOrderQuantity(CompanySellerProfitParam choseMonth) {
        String startTime= TimeUtils.getStartTimeOfCurrentMonth();
        String endTime=TimeUtils.getCurrentTime();
        List<String> monthStartAndEnd = Lists.newArrayList();
        if (ObjectUtils.isNotNull(choseMonth)) {
            monthStartAndEnd = getMonthStartAndEnd(choseMonth.getChoseMonth());
        }
        if (CollUtil.isNotEmpty(monthStartAndEnd)) {
            startTime = monthStartAndEnd.get(0);
            endTime = monthStartAndEnd.get(1);
        }
        log.info("endTime:{}", endTime);
        return orderMapper.getDailyOrderQuantity(startTime, endTime);
    }

    @Override
    public List<UserWeekSumAmountDto> getWeekTopRateByUserData(List<Integer> orderNormalStatus) {
        List<Long> userIds = orderMapper.getTopAmountUserByThisWeek(orderNormalStatus);
        return Optional.ofNullable(userIds).isPresent() && !userIds.isEmpty() ? orderMapper.getWeekTopAmountByUserDate(userIds, orderNormalStatus) : Lists.newArrayList();
    }

    @Override
    public List<UserWeekSumAmountDto> getUserWeekAmountNum(Integer sellerId, List<Integer> orderNormalStatus) {
        return orderMapper.getUserWeekAmountNum(sellerId, orderNormalStatus);
    }

    @Override
    public List<UserWeekSumAmountDto> getWeekAmountNum(Integer userId, List<Integer> orderNormalStatus) {
        return orderMapper.getWeekAmountNum(userId, orderNormalStatus);
    }

    /**
     * 每月各销售名下客户按天金额
     *
     * @return
     */
    @Override
    public List<DailyOrderAmountGroupbySellerVO> dailyAmountGroupBySeller() {
        String startTime = TimeUtils.getStartTimeOfCurrentMonth();
        String endTime = TimeUtils.getCurrentTime();
        List<DailyOrderAmountGroupbySellerVO> dailyOrderAmountGroupbySellerVOS = orderMapper.dailyOrderAmountGroupbySellerVO(startTime, endTime);
        return dailyOrderAmountGroupbySellerVOS;
    }

    /**
     * @Author: hhp
     * @Description: 当天消费前十的用户当前周每个用户每天的消费订单数据  24-07-23 需求变更 展示当日消费前十用户数据
     * @Data: 2024/7/22 11:25
     * @param    orderNormalStatus
     * @return: java.util.List<com.jinke.api.modules.ums.dto.UserWeekDaySumAmountDto>
     * @throws:
     **/
    @Override
    public List<UserWeekDaySumAmountDto> getWeekTopRateByUserEveryDay(List<Integer> orderNormalStatus) {
        List<UmsAdmin> topTenUsers = orderMapper.getTopAmountUserByCurDay(orderNormalStatus);
        if(CollUtil.isNotEmpty(topTenUsers)) {
            List<Long> userIds = topTenUsers.stream().map(item -> {
                return Long.valueOf(item.getId());
            }).collect(Collectors.toList());
            // 表未用join 这里再查一下用户表 拿到用户姓名
            List<UmsAdmin> umsAdmins = umsAdminService.list(new LambdaQueryWrapper<UmsAdmin>().in(UmsAdmin::getId, userIds)
                    .select(UmsAdmin::getId, UmsAdmin::getRealName, UmsAdmin::getUsername, UmsAdmin::getEmail));

            //Integer[] weekDays = new Integer[]{1,2,3,4,5,6,7};
            List<String> weekDates = Lists.newArrayList();
            LocalDate today = LocalDate.now();
            LocalDate monday = today.with(DayOfWeek.MONDAY);
            LocalDate sunday = today.with(DayOfWeek.SUNDAY);

            String startTime = monday.toString() + " 00:00:00";
            String endTiem = sunday.toString() + " 23:59:59";

            // WEEK 按周日到周一 该成 createTime > and < 或者返回的数据过滤掉 上周日的数据
            List<UserWeekSumAmountDto> weekTopUserDays = orderMapper.getWeekTopRateByUserEveryDay(userIds, orderNormalStatus, startTime, endTiem);

            for (LocalDate date = monday; date.isBefore(sunday.plusDays(1)); date = date.plusDays(1)) {
                weekDates.add(date.toString());
            }

            List<UserWeekDaySumAmountDto> userWeekDayDatas = umsAdmins.stream().map(umsAdmin -> {
                long userId = Long.valueOf(umsAdmin.getId());

                UserWeekDaySumAmountDto userWeekDay = new UserWeekDaySumAmountDto();
                userWeekDay.setUserId(userId);
                userWeekDay.setRealName(StrUtil.isNotBlank(umsAdmin.getRealName()) ? umsAdmin.getRealName() : umsAdmin.getUsername());
                userWeekDay.setEmail(umsAdmin.getEmail());
                List<UserWeekSumAmountDto> currentUserWeekDayDatas = weekTopUserDays.stream().filter(weekTopUserDay -> {
                    return weekTopUserDay.getUserId().equals(userId);
                }).collect(Collectors.toList());

                //List<Integer> needAddEmptyWeeks = Arrays.stream(weekDays).filter(week -> currentUserWeekDayDatas.stream().noneMatch(item -> item.getWeek().equals(week))).collect(Collectors.toList());
                List<String> needAddEmptyWeekDates = weekDates.stream().filter(whichDate -> currentUserWeekDayDatas.stream().noneMatch(item -> item.getOrderDate().equals(whichDate))).collect(Collectors.toList());

                /*needAddEmptyWeeks.forEach(week -> {
                    UserWeekSumAmountDto userWeekSumAmountDto = new UserWeekSumAmountDto();
                    userWeekSumAmountDto.setWeek(week);
                    userWeekSumAmountDto.setUserId(userId);
                    userWeekSumAmountDto.setTotalAmount(BigDecimal.ZERO);
                    userWeekSumAmountDto.setOrderNum(0);
                    currentUserWeekDayDatas.add(userWeekSumAmountDto);
                });*/
                needAddEmptyWeekDates.forEach(weekDate -> {
                    UserWeekSumAmountDto userWeekSumAmountDto = new UserWeekSumAmountDto();
                    //userWeekSumAmountDto.setWeek(week);
                    userWeekSumAmountDto.setUserId(userId);
                    userWeekSumAmountDto.setTotalAmount(BigDecimal.ZERO);
                    userWeekSumAmountDto.setOrderNum(0);
                    userWeekSumAmountDto.setOrderDate(weekDate);
                    currentUserWeekDayDatas.add(userWeekSumAmountDto);
                });

                /*userWeekDay.setWeekDay(currentUserWeekDayDatas.stream().peek(userWeekSumAmountDto -> {
                    userWeekSumAmountDto.setWeek(userWeekSumAmountDto.getWeek()-1);
                    if (userWeekSumAmountDto.getWeek().equals(0)) {
                        userWeekSumAmountDto.setWeek(7);
                    }
                }).sorted((UserWeekSumAmountDto userWeekDay1, UserWeekSumAmountDto userWeekDay2) -> {
                    return userWeekDay1.getWeek().compareTo(userWeekDay2.getWeek());
                }).collect(Collectors.toList()));*/
                userWeekDay.setWeekDay(currentUserWeekDayDatas.stream().sorted((UserWeekSumAmountDto userWeekDay1, UserWeekSumAmountDto userWeekDay2) -> {
                    return userWeekDay1.getOrderDate().compareTo(userWeekDay2.getOrderDate());
                }).collect(Collectors.toList()));
                return userWeekDay;
            }).collect(Collectors.toList());

            return userWeekDayDatas;
        } else {
            return Lists.newArrayList();
        }
    }

    /**
     * @Author: hhp
     * @Description: 销售关联的用户当前周每个人每天的订单统计数据
     * @Data: 2024/7/22 14:24
     * @param   sellerId
     * @param    orderNormalStatus
     * @return:  <com.jinke.api.modules.ums.dto.UserWeekDaySumAmountDto>
     * @throws:
     **/
    @Override
    public List<UserWeekDaySumAmountDto> getUserWeekDayAmountNum(Integer sellerId, List<Integer> orderNormalStatus) {
        // 销售关联的可用的用户
        List<UmsAdmin> sellerUsers = umsAdminService.list(new LambdaQueryWrapper<UmsAdmin>().eq(UmsAdmin::getSellerId, sellerId).eq(UmsAdmin::getStatus, ChannelStatus.ON).select(UmsAdmin::getId));
        if(CollUtil.isNotEmpty(sellerUsers)) {
            // 24-07-23 需求变更 展示当日消费前十用户数据
            // 消费前十用户的id
            List<UmsAdmin> collectTopUsers = orderMapper.getTopAmountUserBySellerCurDay(sellerUsers, orderNormalStatus);
            if (CollUtil.isEmpty(collectTopUsers)) {
                int maxUserNum = Math.min(sellerUsers.size(), 10);
                for (int i=0; i < maxUserNum; i++) {
                    collectTopUsers.add(sellerUsers.get(i));
                }
            }
            // 拿到消费前十用户名字
            List<UmsAdmin> topUsers = umsAdminService.list(new LambdaQueryWrapper<UmsAdmin>().
                    in(UmsAdmin::getId, collectTopUsers.stream().map(UmsAdmin::getId).collect(Collectors.toList()))
                    .eq(UmsAdmin::getStatus, ChannelStatus.ON).select(UmsAdmin::getId, UmsAdmin::getRealName, UmsAdmin::getUsername, UmsAdmin::getEmail));

            //Integer[] weekDays = new Integer[]{1,2,3,4,5,6,7};
            List<String> weekDates = Lists.newArrayList();
            LocalDate today = LocalDate.now();
            LocalDate monday = today.with(DayOfWeek.MONDAY);
            LocalDate sunday = today.with(DayOfWeek.SUNDAY);

            String startTime = monday.toString() + " 00:00:00";
            String endTiem = sunday.toString() + " 23:59:59";

            // 销售关联的用户当前周每个人每天订单统计数据
            List<UserWeekSumAmountDto> weekTopUserDays = orderMapper.getUserWeekDayAmountNum(topUsers, orderNormalStatus, startTime, endTiem);

            for (LocalDate date = monday; date.isBefore(sunday.plusDays(1)); date = date.plusDays(1)) {
                weekDates.add(date.toString());
            }
            List<UserWeekDaySumAmountDto> userWeekDayDatas = topUsers.stream().map(umsAdmin -> {
                long userId = Long.valueOf(umsAdmin.getId());
                UserWeekDaySumAmountDto userWeekDay = new UserWeekDaySumAmountDto();
                userWeekDay.setUserId(userId);
                userWeekDay.setRealName(StrUtil.isNotBlank(umsAdmin.getRealName()) ? umsAdmin.getRealName() : umsAdmin.getUsername());
                userWeekDay.setEmail(umsAdmin.getEmail());
                List<UserWeekSumAmountDto> currentUserWeekDayDatas = weekTopUserDays.stream().filter(weekTopUserDay -> {
                    return weekTopUserDay.getUserId().equals(userId);
                }).collect(Collectors.toList());

                //List<Integer> needAddEmptyWeeks = Arrays.stream(weekDays).filter(week -> currentUserWeekDayDatas.stream().noneMatch(item -> item.getWeek().equals(week))).collect(Collectors.toList());
                List<String> needAddEmptyWeekDates = weekDates.stream().filter(weekDate -> currentUserWeekDayDatas.stream().noneMatch(item -> item.getOrderDate().equals(weekDate))).collect(Collectors.toList());

                /*needAddEmptyWeeks.forEach(week -> {
                    UserWeekSumAmountDto userWeekSumAmountDto = new UserWeekSumAmountDto();
                    userWeekSumAmountDto.setWeek(week);
                    userWeekSumAmountDto.setUserId(userId);
                    userWeekSumAmountDto.setTotalAmount(BigDecimal.ZERO);
                    userWeekSumAmountDto.setOrderNum(0);
                    currentUserWeekDayDatas.add(userWeekSumAmountDto);
                });*/
                needAddEmptyWeekDates.forEach(weekDate -> {
                    UserWeekSumAmountDto userWeekSumAmountDto = new UserWeekSumAmountDto();
                    //userWeekSumAmountDto.setWeek(week);
                    userWeekSumAmountDto.setUserId(userId);
                    userWeekSumAmountDto.setTotalAmount(BigDecimal.ZERO);
                    userWeekSumAmountDto.setOrderNum(0);
                    userWeekSumAmountDto.setOrderDate(weekDate);
                    currentUserWeekDayDatas.add(userWeekSumAmountDto);
                });

                /*userWeekDay.setWeekDay(currentUserWeekDayDatas.stream().peek(userWeekSumAmountDto -> {
                    userWeekSumAmountDto.setWeek(userWeekSumAmountDto.getWeek()-1);
                    if (userWeekSumAmountDto.getWeek().equals(0)) {
                        userWeekSumAmountDto.setWeek(7);
                    }
                }).sorted((UserWeekSumAmountDto userWeekDay1, UserWeekSumAmountDto userWeekDay2) -> {
                    return userWeekDay1.getWeek().compareTo(userWeekDay2.getWeek());
                }).collect(Collectors.toList()));*/
                userWeekDay.setWeekDay(currentUserWeekDayDatas.stream().sorted((UserWeekSumAmountDto userWeekDay1, UserWeekSumAmountDto userWeekDay2) -> {
                    return userWeekDay1.getOrderDate().compareTo(userWeekDay2.getOrderDate());
                }).collect(Collectors.toList()));
                return userWeekDay;
            }).collect(Collectors.toList());

            return userWeekDayDatas;
        } else {
            return Lists.newArrayList();
        }
    }

    /**
     * @Author: hhp
     * @Description: 当前登录用户当前周每天订单统计数据
     * @Data: 2024/7/22 14:25
     * @param    orderNormalStatus
     * @return:  <com.jinke.api.modules.ums.dto.UserWeekDaySumAmountDto>
     * @throws:
     **/
    @Override
    public List<UserWeekDaySumAmountDto> getWeekDayAmountNum(UmsAdmin userInfo, List<Integer> orderNormalStatus) {
        // Integer[] weekDays = new Integer[]{1,2,3,4,5,6,7};
        List<String> weekDates = Lists.newArrayList();
        LocalDate today = LocalDate.now();
        LocalDate monday = today.with(DayOfWeek.MONDAY);
        LocalDate sunday = today.with(DayOfWeek.SUNDAY);

        String startTime = monday.toString() + " 00:00:00";
        String endTiem = sunday.toString() + " 23:59:59";

        List<UserWeekSumAmountDto> weekTopUserDays = orderMapper.getWeekDayAmountNum(userInfo.getId(), orderNormalStatus, startTime, endTiem);

        for (LocalDate date = monday; date.isBefore(sunday.plusDays(1)); date = date.plusDays(1)) {
            weekDates.add(date.toString());
        }
        List<UserWeekDaySumAmountDto> resultData = Lists.newArrayList();

        UserWeekDaySumAmountDto userWeekDaySumAmountDto = new UserWeekDaySumAmountDto();
        userWeekDaySumAmountDto.setUserId(Long.valueOf(userInfo.getId()));
        userWeekDaySumAmountDto.setRealName(StrUtil.isNotBlank(userInfo.getRealName()) ? userInfo.getRealName() : userInfo.getUsername());
        userWeekDaySumAmountDto.setEmail(userInfo.getEmail());

        //List<Integer> needAddEmptyWeeks = Arrays.stream(weekDays).filter(week -> weekTopUserDays.stream().noneMatch(item -> item.getWeek().equals(week))).collect(Collectors.toList());
        List<String> needAddEmptyWeekDates = weekDates.stream().filter(weekDate -> weekTopUserDays.stream().noneMatch(item -> item.getOrderDate().equals(weekDate))).collect(Collectors.toList());

        /*needAddEmptyWeeks.forEach(week -> {
            UserWeekSumAmountDto userWeekSumAmountDto = new UserWeekSumAmountDto();
            userWeekSumAmountDto.setWeek(week);
            userWeekSumAmountDto.setUserId(Long.valueOf(userInfo.getId()));
            userWeekSumAmountDto.setTotalAmount(BigDecimal.ZERO);
            userWeekSumAmountDto.setOrderNum(0);
            weekTopUserDays.add(userWeekSumAmountDto);
        });*/
        needAddEmptyWeekDates.forEach(weekDate -> {
            UserWeekSumAmountDto userWeekSumAmountDto = new UserWeekSumAmountDto();
            //userWeekSumAmountDto.setWeek(week);
            userWeekSumAmountDto.setUserId(Long.valueOf(userInfo.getId()));
            userWeekSumAmountDto.setTotalAmount(BigDecimal.ZERO);
            userWeekSumAmountDto.setOrderNum(0);
            userWeekSumAmountDto.setOrderDate(weekDate);
            weekTopUserDays.add(userWeekSumAmountDto);
        });
        /*userWeekDaySumAmountDto.setWeekDay(weekTopUserDays.stream().peek(userWeekSumAmountDto -> {
            userWeekSumAmountDto.setWeek(userWeekSumAmountDto.getWeek()-1);
            if (userWeekSumAmountDto.getWeek().equals(0)) {
                userWeekSumAmountDto.setWeek(7);
            }
        }).sorted((UserWeekSumAmountDto userWeekDay1, UserWeekSumAmountDto userWeekDay2) -> {
            return userWeekDay1.getWeek().compareTo(userWeekDay2.getWeek());
        }).collect(Collectors.toList()));*/
        userWeekDaySumAmountDto.setWeekDay(weekTopUserDays.stream().sorted((UserWeekSumAmountDto userWeekDay1, UserWeekSumAmountDto userWeekDay2) -> {
            return userWeekDay1.getOrderDate().compareTo(userWeekDay2.getOrderDate());
        }).collect(Collectors.toList()));
        resultData.add(userWeekDaySumAmountDto);
        return resultData;
    }

    /**
     * @Author: hhp
     * @Description: 销售关联的用户当日订单统计数据
     * @Data: 2024/7/23 9:12
     * @param    allSellerUsers 所有销售关联的用户
     * @param    orderNormalStatus 正常订单状态
     * @return:  <com.jinke.api.modules.ums.dto.UserDayOrderProfitDto>
     * @throws:
     **/
    @Override
    public List<UserDayOrderProfitDto> getAllSellerUserDay(List<UmsAdmin> allSellerUsers, List<Integer> orderNormalStatus) {
        return orderMapper.getAllSellerUserDay(allSellerUsers, orderNormalStatus);
    }

    /**
     * @Author: hhp
     * @Description:
     * @Data: 2024/7/24 11:17
     * @param   choseMonth 月份
     * @param    orderNormalStatus
     * @return:  <com.jinke.api.modules.ums.dto.UserMonthStatisticsDto>
     * @throws:
     **/
    @Override
    public List<UserMonthStatisticsDto> getSellerPerformanceStatistics(CompanySellerProfitParam choseMonth, List<Integer> orderNormalStatus) {
        return orderMapper.getUserMonthStatistics(choseMonth, orderNormalStatus);
    }

    @Override
    public List<UserMonthStatisticsDto> getSellerPerformanceStatisticsBySId(CompanySellerProfitParam choseMonth, List<Integer> orderNormalStatus) {
        return orderMapper.getSellerPerformanceStatisticsBySId(choseMonth, orderNormalStatus);
    }

    @Override
    public List<UserMonthStatisticsDto> getSingleSellerPerformanceStatisticsBySId(CompanySellerProfitParam choseMonth, List<Integer> orderNormalStatus, Integer wzId) {
        return orderMapper.getSingleSellerPerformanceStatisticsBySId(choseMonth, orderNormalStatus, wzId);
    }

    @Override
    public List<DailyOrderAmountGroupbySellerVO> dailyAmountGroupBySingleSeller(Integer sellerId) {
        String startTime = TimeUtils.getStartTimeOfCurrentMonth();
        String endTime = TimeUtils.getCurrentTime();
        List<DailyOrderAmountGroupbySellerVO> dailyOrderAmountGroupbySellerVOS = orderMapper.dailyOrderAmountGroupbySingleSellerVO(startTime, endTime, sellerId);
        return dailyOrderAmountGroupbySellerVOS;
    }

    /**
     * @Author: hhp
     * @Description: 根据前端传的参数更新对应信息
     * @Data: 2024/8/26 14:45
     * @param request
     * @return: com.jinke.api.common.api.CommonResult<java.lang.String>
     * @throws:
     **/
    @Override
    public CommonResult<String> updateByParamType(OrderSupplementaryRequest request) {
        String orderNo = request.getOrderNo();
        // 做三个方法 三个事务互相隔离 只要自己的功能完成就行 不影响彼此回滚
        String pdfUrl = request.getPdfUrl();
        if (StrUtil.isNotBlank(pdfUrl)) {
            boolean updatePdfUrlResult = updateByPdfUrlParam(orderNo, pdfUrl);
            log.info("补寄件扣费-更新PDF{},{},{}",orderNo,pdfUrl, updatePdfUrlResult);

        }

        String trackingNumber = request.getTrackingNumber();
        if (StrUtil.isNotBlank(trackingNumber)) {
            boolean updateTrackingNumberResult = updateByTrackingNumberParam(orderNo, trackingNumber);
            log.info("补寄件扣费-更新物流号{},{},{}",orderNo,trackingNumber, updateTrackingNumberResult);
        }

        String rate = request.getRate();
        if (StrUtil.isNotBlank(rate)) {
            updateByRateParam(orderNo, rate);
            log.info("补寄件扣费-明细:{},{}", rate, orderNo);
        }
        return CommonResult.success("更新成功，请刷新订单列表");
    }
    /**
     * 更新
     *
     * @param orderIdsWithInfo
     * @param orderMap
     */
    @Override
    public void updatePacelstatusByOrderIds(Set<Integer> orderIdsWithInfo, Map<Integer, Order> orderMap) {
            if (orderIdsWithInfo.isEmpty()) {
                return;
            }
            UpdateWrapper<OrderParcel> wa = new UpdateWrapper<>();
            wa.lambda().set(OrderParcel::getStatus, OrderParcelStatus.IN_TRANSIT.getValue()).in(
                    OrderParcel::getOrderId, orderIdsWithInfo

            );
            orderParcelService.update(wa);
        }

    @Override

    /**
     * 根据订单信息取消
     *
     * @param orderIdsWithInfo
     * @param orderMap
     */
    public void cancelNoByOrderId(Set<Integer> orderIdsWithInfo, Map<Integer, Order> orderMap) {
        if (orderIdsWithInfo.isEmpty()) {
            return;
        }

        Set<Integer> channelIdSet = new HashSet<>();
        for (Integer orderId : orderIdsWithInfo) {
            Order order = orderMap.get(orderId);
            channelIdSet.add(order.getChannelId());
        }

        List<Channel> channelList = channelService.getChannelByPKs(channelIdSet);
        Map<Integer, Channel> channelMap = channelList.stream().collect(Collectors.toMap(Channel::getId, Function.identity()));
        for (Integer orderId : orderIdsWithInfo) {
            Order order = orderMap.get(orderId);
            Channel channel = channelMap.get(order.getChannelId());

            //只取消UPS+FEDEX
            if (channel.getServiceCode().startsWith("FedEx") || channel.getServiceCode().startsWith("UPS") || channel.getServiceCode().startsWith("ups")) {
                BaseShipService baseShipService = shipFactory.getBaseShipService(channel);
                CommonResult commonResult = baseShipService.cancelLabel(order.getObjectId(),order.getOrderNo());

                //取消成功后更新记录
                if (commonResult.isSucess() || commonResult.getMessage().equals("订单已删除，无需再次删除")
                        || commonResult.getMessage().equals("撤消成功!") || commonResult.getMessage().equals("OS：订单不存在或未完成或无权限!")) {
                    BigDecimal rate = order.getRate();
                    BigDecimal earnest = order.getEarnest();
                    List<BalanceLog.Detail> details = new ArrayList<>();

                    if (order.getEarnestTime() == null) {
                        // 退还保证金
                        details.add(new BalanceLog.Detail("寄件", rate.toString()));
                        details.add(new BalanceLog.Detail("保证金", earnest.toString()));
                    } else {
                        // 找到保证金退还记录
                        details.add(new BalanceLog.Detail("寄件", rate.toString()));
                        details.add(new BalanceLog.Detail("保证金", BigDecimal.ZERO.toString()));
                    }
                    //如果此人不是admin也变成取消中等待审核
                    order.setStatus(OrderStatus.CANCEL.getValue());
                    //退钱
                    userRechargeService.incr(order.getUserId(), rate.add(earnest), BalanceLogType.REFUND, "退款", order.getOrderNo(), details);
                    order.setStatus(OrderStatus.DRAFT.getValue());
                    order.setCancelTime(LocalDateTime.now());
                    order.setErrMsg("一定时间无物流轨迹自动取消");
                    orderService.updateById(order);
                    log.error(order.getOrderNo() + "无轨迹自动取消成功");
                } else {
                    log.error(order.getOrderNo() + "无轨迹自动取消失败" + commonResult.getMessage());
                }
            }

        }


    }

    @Override
    public List<UserOrderCountVO> getCountGroupByUserId(Set<Integer> userIds, String startDay, String dayEnd) {
        return orderMapper.countGroupByUserId(userIds, startDay, dayEnd);
    }

    @Override
    public List<UserOrderSummaryVO> countGroupByDate( String startDay, String dayEnd, List<Integer> userId  ) {
        return orderMapper.countGroupByDate( startDay, dayEnd,userId);
    }
    @Override
    public List<OrderParcel> selectUserOrderParcels( String startDay, String dayEnd, List<Integer> userId  ) {
        return orderMapper.selectUserOrderParcels( startDay, dayEnd,userId);
    }


    private static List<String> getMonthStartAndEnd(int month) {
        if (ObjectUtils.isNull(month)) {
            return Lists.newArrayList();
        }
        List<String> monthStartEndList = Lists.newArrayList();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, month - 1); // 月份从 0 开始计数，所以要减 1

        // 获取月初时间
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date startOfMonth = calendar.getTime();

        // 获取月末时间
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        Date endOfMonth = calendar.getTime();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = sdf.format(startOfMonth);
        String end = sdf.format(endOfMonth);
        monthStartEndList.add(start);
        monthStartEndList.add(end);
        return monthStartEndList;
    }


    /**
     * @Author: hhp
     * @Description: 开启新事务 单独处理更新pdf地址
     * @Data: 2024/8/26 15:40
     * @param orderNo
     * @param pdfUrl
     * @return: boolean
     * @throws:
     **/
    public boolean updateByPdfUrlParam(String orderNo, String pdfUrl) {
        // 如果 pdf有值更新orderno对应的user_order
        //把订单的pdfurl传到oss 换成我们的地址
        String objectId= CommonUtil.getOrderNo();
        ossUtil.upload("pdf", objectId + ".pdf", pdfUrl);
        String newLabelUrl = Global.PRINT_LABEL_API + objectId;
        return orderService.update(
                Wrappers.<Order>lambdaUpdate()
                        .eq(Order::getOrderNo, orderNo)
                        .set(Order::getCreateTime , LocalDateTime.now())
                        .set(Order::getStatus, OrderStatus.IN_TRANSIT)
                        .set(Order::getPdfUrl,newLabelUrl ));
    }

    /**
     * @Author: hhp
     * @Description: 开启新事物 单独处理更新包裹事件
     * @Data: 2024/8/26 15:41
     * @param orderNo
     * @param trackingNumber
     * @return: boolean
     * @throws:
     **/
    public boolean updateByTrackingNumberParam(String orderNo, String trackingNumber) {
        // trackingnumber有值 更新订单对应的包裹表
        List<Order> orders = Optional.ofNullable(
                orderService.lambdaQuery().eq(Order::getOrderNo, orderNo).select(Order::getId).list()
        ).orElse(Lists.newArrayList());
        if (!orders.isEmpty()) {
            // set集合不会重复自带去重
            return orderParcelService.update(
                    Wrappers.<OrderParcel>lambdaUpdate()
                            .in(OrderParcel::getOrderId, orders.stream().map(Order::getId).collect(Collectors.toSet()))
                            .set(OrderParcel::getTrackingNumber, trackingNumber));
        }
        return false;
    }

    /**
     * @Author: hhp
     * @Description: 开启新事务 单独处理rate更新 及 扣钱
     * @Data: 2024/8/26 15:57
     * @param   orderNo
     * @param   rate
     * @return: boolean
     * @throws:
     **/
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public boolean updateByRateParam(String orderNo, String rate) {
        BigDecimal amount = new BigDecimal(rate);
        Order order = orderService.lambdaQuery()
                .eq(Order::getOrderNo, orderNo)
                .select(Order::getId, Order::getUserId, Order::getObjectId).one();

        Integer userId = order.getUserId();
        UmsAdmin umsAdmin = umsAdminService.getById(userId);
        BigDecimal earnestRate = umsAdmin.getEarnestRate();
        BigDecimal subEarnestBalance = MathUtil.formatBigDecimal(amount.multiply(earnestRate));
        order.setEarnest(subEarnestBalance);
        order.setRate(amount);

        // 如果 pdf有值更新orderno对应的user_order
        orderService.updateById(order );

        // 扣钱
        userRechargeService.decrTransfer(userId, amount, BalanceLogType.BILLED,"寄件扣费", orderNo, null, null,null);

        return true;
    }

    /**
     * 统计发送无轨迹
     * @param orderNo
     * @param rate
     * @return
     */
    public void summaryNoLogister( List<Integer>    summaryUserId,    String startDay, String endDay) {
        String title = startDay+"-"+endDay+"轨迹统计";
        log.info("==================JOB"+title+"开始=============");
        //查db
        List<UserOrderSummaryVO> oneWeekAgoSummaryNew = orderService.countGroupByDate(startDay, endDay,summaryUserId);
        List<Integer> userIdList = oneWeekAgoSummaryNew.stream().map(UserOrderSummaryVO::getUserId).collect(Collectors.toList());

        //查询用户信息
        Map<Integer, SimpleUser> adminMap = adminService.getMaps(userIdList);
        Map<Integer, List<UserOrderSummaryVO>> groupedByUserId = oneWeekAgoSummaryNew.stream()
                .collect(Collectors.groupingBy(UserOrderSummaryVO::getUserId));

        List<String> tachengMsg = new ArrayList<>();


        groupedByUserId.forEach((userId, userOrderSummaryList) -> {
            log.info("User ID: " + userId);
            SimpleUser simpleUser = adminMap.get(userId);

            for (UserOrderSummaryVO userOrderSummaryVO : userOrderSummaryList) {
                String orderDate = userOrderSummaryVO.getOrderDate();
                //按人按天查待运输的订单号
                LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
                //查订单id 订单号和平台号
                queryWrapper.select(Order::getId
                );
                //指定先更新某着急的客户的
                queryWrapper.eq(userId != null, Order::getUserId, userId);
                queryWrapper.eq(  Order::getStatus,  OrderStatus.RECENT);
                //当天
                queryWrapper.lt(Order::getCreateTime, orderDate+" 23:59:59");
                queryWrapper .gt(Order::getCreateTime, orderDate+" 00:00:00");

                //订单号转包裹号
                List<Order> list = orderService.list(queryWrapper);
                List<Integer> orderIdNoInfo = list.stream().map(Order::getId)
                        .collect(Collectors.toList());
                List<OrderParcel> parcelByOrderIdList = orderParcelService.getParcelByOrderIdList(orderIdNoInfo);
//                List<String> trackingNumbers = parcelByOrderIdList.stream().map(OrderParcel::getTrackingNumber).collect(Collectors.toList());

              // qucha1(trackingNumbers);
                //物流号
                userOrderSummaryVO.setParcelByOrderIdList(parcelByOrderIdList);

            }

            //附件
            MockMultipartFile multipartFile = FileUtil.toExcel(userOrderSummaryList);
            if (multipartFile!=null){

                //上传返回下载链接
                String txtDownloadURL = ossUtil.upload("txtDownloadURL", multipartFile);
                //所有塔城生成一条
                String msgHtml = CommonUtil.createMsgHtml(userOrderSummaryList, simpleUser.getRealName(), txtDownloadURL);
                if (CommonUtil.checkTC(userId)) {
                    //一起发
                    tachengMsg.add(msgHtml);

                } else {
                    //一个个发
                    Thread thread = new Thread(() -> {
                        try {
                            TimeUnit.SECONDS.sleep(2);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        //发邮件
                        sysMessageService.sendMailToUs(msgHtml, null, title, simpleUser.getEmail());
                    });
                    thread.start();

                }
            }


        });
        //tacheng只发一封
        String s = tachengMsg.toString();

        //多封内容合成一封
        String htmlContent = s.substring(1, s.length() - 1);
        log.info("duoheyi"+htmlContent);
        sysMessageService.sendMailToUs(htmlContent, null, title, Global.EMAIL_TACHENG);
        log.info("==================JOB"+title+"结束=============");
    }

    /**
     * 只发塔城的统计
     * @param summaryUserId
     * @param startDay
     * @param endDay
     */
    public void onlyTAcheng( List<Integer>    summaryUserId,    String startDay, String endDay) {
        String title = startDay+"-"+endDay+"轨迹统计";
        log.info("==================JOB"+title+"开始=============");
        //查db
        List<UserOrderSummaryVO> oneWeekAgoSummaryNew = orderService.countGroupByDate(startDay, endDay,summaryUserId);
        List<Integer> userIdList = oneWeekAgoSummaryNew.stream().map(UserOrderSummaryVO::getUserId).collect(Collectors.toList());

        //查询用户信息
        Map<Integer, SimpleUser> adminMap = adminService.getMaps(userIdList);
        Map<Integer, List<UserOrderSummaryVO>> groupedByUserId = oneWeekAgoSummaryNew.stream()
                .collect(Collectors.groupingBy(UserOrderSummaryVO::getUserId));

        List<String> tachengMsg = new ArrayList<>();


        groupedByUserId.forEach((userId, userOrderSummaryList) -> {
            log.info("User ID: " + userId);
            SimpleUser simpleUser = adminMap.get(userId);

            for (UserOrderSummaryVO userOrderSummaryVO : userOrderSummaryList) {
                String orderDate = userOrderSummaryVO.getOrderDate();
                //按人按天查待运输的订单号
                LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
                //查订单id 订单号和平台号
                queryWrapper.select(Order::getId
                );
                //指定先更新某着急的客户的
                queryWrapper.eq(userId != null, Order::getUserId, userId);
                queryWrapper.eq(  Order::getStatus,  OrderStatus.RECENT);
                //当天
                queryWrapper.lt(Order::getCreateTime, orderDate+" 23:59:59");
                queryWrapper .gt(Order::getCreateTime, orderDate+" 00:00:00");

                //订单号转包裹号
                List<Order> list = orderService.list(queryWrapper);
                List<Integer> orderIdNoInfo = list.stream().map(Order::getId)
                        .collect(Collectors.toList());
                List<OrderParcel> parcelByOrderIdList = orderParcelService.getParcelByOrderIdList(orderIdNoInfo);
//                List<String> trackingNumbers = parcelByOrderIdList.stream().map(OrderParcel::getTrackingNumber).collect(Collectors.toList());

              // qucha1(trackingNumbers);
                //物流号
                userOrderSummaryVO.setParcelByOrderIdList(parcelByOrderIdList);

            }

            //附件
            MockMultipartFile multipartFile = FileUtil.toExcel(userOrderSummaryList);
            if (multipartFile!=null){

                //上传返回下载链接
                String txtDownloadURL = ossUtil.upload("txtDownloadURL", multipartFile);
                //所有塔城生成一条
                String msgHtml = CommonUtil.createMsgHtml(userOrderSummaryList, simpleUser.getRealName(), txtDownloadURL);
                tachengMsg.add(msgHtml);

            }


        });
        //tacheng只发一封
        String s = tachengMsg.toString();

        //多封内容合成一封
        String htmlContent = s.substring(1, s.length() - 1);
        log.info("duoheyi"+htmlContent);
        sysMessageService.sendMailToUs(htmlContent, null, title, Global.HUSURUO);
        sysMessageService.sendMailToUs(htmlContent, null, title, Global.YANGXI);
        log.info("==================JOB"+title+"结束=============");
    }

    @Override
    public void logistoryRealOrNot(List<OrderParcel> parcels) {

        List<List<String>> batchedTrackingNumbers = batchTrackingNumbers(parcels);

        List<OrderParcel> processedParcels = new ArrayList<>();

        HashMap<String, Integer> zz=new HashMap<>();
        for (int j = 0; j < batchedTrackingNumbers.size(); j++) {

            List<String> batch = batchedTrackingNumbers.get(j);
            //api
            HashMap<String, Integer> preOnlineStatuses = checkPreOnlineStatus(batch);

            System.out.println(preOnlineStatuses);
            for (String key : preOnlineStatuses.keySet()) {
                if (zz.containsKey(key)) {
                    // 如果键已经存在，你可以根据需求决定是覆盖还是做其他处理，这里简单覆盖
                    zz.put(key, preOnlineStatuses.get(key));
                } else {
                    zz.put(key, preOnlineStatuses.get(key));
                }
            }

        }


        for (int i = 0; i < parcels.size(); i++) {

            OrderParcel parcel =  parcels.get(i);
            Integer integer = zz.get(parcel.getTrackingNumber());
            if (integer == null) {
                //异常
                parcel.setStatus(-3);

            }else {

                if (integer==1) {
                    parcel.setStatus(1);
                } else {
                    parcel.setStatus(0);
                }
            }
            System.out.println("------------****"+parcel.getStatus());
            processedParcels.add(parcel);
        }

        generateExcel(processedParcels);

    }
    private static List<List<String>> batchTrackingNumbers(List<OrderParcel> parcels) {
        List<List<String>> batches = new ArrayList<>();
        List<String> batch = new ArrayList<>();
        for (OrderParcel parcel : parcels) {
            batch.add(parcel.getTrackingNumber());
            if (batch.size() == 40) {
                batches.add(batch);
                batch = new ArrayList<>();
            }
        }
        if (!batch.isEmpty()) {
            batches.add(batch);
        }
        return batches;
    }

    private   boolean checkTrackingInfo(JSONObject tracking) {
        if (tracking == null) {
            return false;
        }
        JSONArray providers = tracking.getJSONArray("providers");
        if (providers == null || providers.isEmpty()) {
            return false;
        }
        JSONObject provider = providers.getJSONObject(0);
        if (provider == null) {
            return false;
        }
        JSONArray events = provider.getJSONArray("events");
        if (events == null || events.size()!= 1) {
            return false;
        }
        JSONObject event = events.getJSONObject(0);
        if (event == null) {
            return false;
        }
        String description = event.getString("description");
        return description!= null && description.contains("SSK");
    }

    private   HashMap<String, Integer> checkPreOnlineStatus(List<String> trackingNumbers) {
        HashMap<String, Integer> objectObjectHashMap = new HashMap<>();
        for (int i = 0; i < trackingNumbers.size(); i += 40) {
            List<String> batchData = trackingNumbers.subList(i, Math.min(trackingNumbers.size(), i + 40));
            String trackInfo = Optional.ofNullable(TrackApiUtils.getTrackinfo(batchData)).orElse("{}");
            JSONObject jsonBody = JSONObject.parseObject(trackInfo);
            Integer code = jsonBody.getInteger("code");
            if (code!= null && code == 0) {
                JSONObject data = Optional.ofNullable(jsonBody.getJSONObject("data")).orElse(new JSONObject());
                JSONArray accepted = Optional.ofNullable(data.getJSONArray("accepted")).orElse(new JSONArray());
                System.out.println(accepted.size()+"---接口返回");
                for (int j = 0; j < accepted.size(); j++) {
                    JSONObject item = accepted.getJSONObject(j);
                    String number = item.getString("number");
                    JSONObject track_info = item.getJSONObject("track_info");
                    JSONObject tracking = track_info.getJSONObject("tracking");
                    boolean b = checkTrackingInfo(tracking);
                    if (!b){
                        //正常
                        objectObjectHashMap.put(number,1);
                    }else {
                        objectObjectHashMap.put(number,0);

                    }
                }
            }
//            else {
//                // 如果接口返回不是预期结果，这里可以根据实际情况处理，比如默认设置为非预上网状态
//                for (int j = i; j < Math.min(trackingNumbers.size(), i + 40); j++) {
//                    statuses.add(new PreOnlineStatus(false));
//                }
//            }
        }
        return objectObjectHashMap;
    }


    private static void generateExcel(List<OrderParcel> parcels) {
        long timestamp = System.currentTimeMillis();
        try (Workbook workbook = new XSSFWorkbook();

             FileOutputStream fileOut = new FileOutputStream("parcels"+timestamp+".xlsx")) {
            Sheet sheet = workbook.createSheet("Parcels");
            Row headerRow = sheet.createRow(0);
            headerRow.createCell(0).setCellValue("Tracking Number");
            headerRow.createCell(1).setCellValue("Status");
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy - MM - dd HH:mm:ss");

            for (int i = 0; i < parcels.size(); i++) {
                OrderParcel parcel = parcels.get(i);
                Row row = sheet.createRow(i + 1);
                row.createCell(0).setCellValue(parcel.getTrackingNumber());
                LocalDateTime createdAt = parcel.getCreatedAt();
                row.createCell(1).setCellValue(parcel.getCreatedAt().format(formatter));

                row.createCell(2).setCellValue(parcel.getStatus());
            }

            workbook.write(fileOut);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 最多40条一查
     * @param trackingNumbers
     * @return
     */
    public   String[] groupList(List<String> trackingNumbers) {
        int size = trackingNumbers.size();
        int groupCount = (size + 39) / 40;
        String[] result = new String[groupCount];

        for (int i = 0; i < groupCount; i++) {
            StringBuilder groupBuilder = new StringBuilder();
            int startIndex = i * 40;
            int endIndex = Math.min(startIndex + 40, size);
            for (int j = startIndex; j < endIndex; j++) {
                groupBuilder.append(trackingNumbers.get(j));
                if (j < endIndex - 1) {
                    groupBuilder.append(",");
                }
            }
            result[i] = groupBuilder.toString();
        }

        return result;
    }

    /**
     * 模拟查网页
     * @param trackingNumbers
     */

    public void qucha1(List<String> trackingNumbers) {
        try {
            // 设置请求的 URL
            String[] strings = this.groupList(trackingNumbers);
            for (int i = 0; i < strings.length; i++) {
                String st=strings[i];
                URL url = new URL("https://t.17track.net/zh-cn#nums="+st);
                // 打开连接
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                // 设置请求方法为 GET
                connection.setRequestMethod("GET");

                // 读取响应
                BufferedReader reader;
                int responseCode = connection.getResponseCode();
                if (responseCode >= 200 && responseCode < 400) {
                    reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                } else {
                    log.info("模拟查询失败");
                    reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
                }
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine())!= null) {
                    response.append(line);
                    System.out.println(line);
                }
                reader.close();

            }




        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /***
     * 查接口 这个就是接口 按这个内容帮我修改下你返回的checkPreOnlineStatus这个方法
     * @param trackingNumbers
     */
    public void quchaByAPI(List<String> trackingNumbers) {
        if (CollectionUtil.isNotEmpty(trackingNumbers)) {
            // 分批次处理数据
            for (int i = 0; i < trackingNumbers.size(); i += 40) {
                List<String> batchData = trackingNumbers.subList(i, Math.min(trackingNumbers.size(), i + 40));
                // 走接口转json时给个无数据的json占位符 转换不会报错
                String trackInfo = Optional.ofNullable(TrackApiUtils.getTrackinfo(batchData)).orElse("{}");
                // 在track17的接口返回中一直没内容 则判断为没用
                com.alibaba.fastjson.JSONObject jsonBody = com.alibaba.fastjson.JSONObject.parseObject(trackInfo);
                Integer code = jsonBody.getInteger("code");

                if (ObjectUtil.isNotNull(code)) {
                    if (code == 0) {
                        com.alibaba.fastjson.JSONObject data = Optional.ofNullable(jsonBody.getJSONObject("data")).orElse(new com.alibaba.fastjson.JSONObject());
                        com.alibaba.fastjson.JSONArray accepted = Optional.ofNullable(data.getJSONArray("accepted")).orElse(new com.alibaba.fastjson.JSONArray());
                        com.alibaba.fastjson.JSONArray rejected = Optional.ofNullable(data.getJSONArray("rejected")).orElse(new com.alibaba.fastjson.JSONArray());

                        // 有物流不做处理
                        for (int j = 0; j < accepted.size(); j++) {
                            com.alibaba.fastjson.JSONObject item = accepted.getJSONObject(j);
                            String number = item.getString("number");
                            com.alibaba.fastjson.JSONObject track_info = item.getJSONObject("track_info");
                            com.alibaba.fastjson.JSONObject latest_status = track_info.getJSONObject("latest_status");
                            String status = latest_status.getString("status");
                            if (status.equals("NotFound")) {
                                System.out.println("status设置成12-----------"+number);

                            }else {
                                System.out.println("status设置成13-----------"+number);

                            }
                        }




                    }
                }
            }

        }
    }

    @Override
    public CommonResult<String> auditByTrackingNum(OrderAuditRequest request) {
        StringBuilder stringBuilder = new StringBuilder();
        List<OrderParcel> orderParcels = Optional.ofNullable(
                orderParcelService.lambdaQuery()
                        .in(OrderParcel::getTrackingNumber, request.getTrackingNos())
                        .select(OrderParcel::getOrderId, OrderParcel::getTrackingNumber).list()
        ).orElse(Lists.newArrayList());
        Set<Integer> orderIds = orderParcels.stream().map(OrderParcel::getOrderId).collect(Collectors.toSet());
        Asserts.isTrue(CollectionUtils.isNotEmpty(orderIds), "物流号没有对应的订单, 请检查物流号后重新提交");
        // 不存在的物流号
        List<String> notExitTNOs = request.getTrackingNos().stream()
                .filter(trackingNo -> orderParcels.stream().noneMatch(orderParcel -> orderParcel.getTrackingNumber().equals(trackingNo)))
                .collect(Collectors.toList());
        List<Order> orders = Optional.ofNullable(
                orderService.lambdaQuery().in(Order::getId, orderIds).select(Order::getId, Order::getOrderNo, Order::getStatus, Order::getUserId).list()
        ).orElse(Lists.newArrayList());
        // 取消中的订单
        List<Order> cancelingOrders = orders.stream().filter(order -> order.getStatus().equals(OrderStatus.CANCEL_ING.getValue())).collect(Collectors.toList());
        // 非取消中的订单
        List<Order> unCancelingOrders = orders.stream().filter(order -> !order.getStatus().equals(OrderStatus.CANCEL_ING.getValue())).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(cancelingOrders)) {
            // 执行审核
            OrderCancelAuditRequest orderCancelAuditRequest = new OrderCancelAuditRequest();
            BeanUtils.copyProperties(request, orderCancelAuditRequest);
            orderCancelAuditRequest.setOrderIds(cancelingOrders.stream().map(order -> { return String.valueOf(order.getId()); }).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList()));
            CommonResult<GetOrdersResponse> getOrdersResponseCommonResult = request.getAccess().equals(1) ? orderService.cancelAudit(orderCancelAuditRequest) : orderService.reject(orderCancelAuditRequest);

            cancelingOrders.forEach(order -> {
                // 可能多个物流对应一个订单 收集全部物流号
                List<OrderParcel> equalsLists = orderParcels.stream().filter(orderParcel -> orderParcel.getOrderId().equals(order.getId())).collect(Collectors.toList());
                String collect = equalsLists.stream().map(OrderParcel::getTrackingNumber).collect(Collectors.joining(","));
                stringBuilder.append(collect);
                stringBuilder.append("对应的订单号:[");
                stringBuilder.append(order.getOrderNo());
                stringBuilder.append("],");
                // 添加换行符，方便查看每个订单的信息
                stringBuilder.append("\n");
            });
            if (StrUtil.isNotBlank(stringBuilder)) {
                String substring = stringBuilder.substring(0, stringBuilder.length() - 1);
                // 清空 StringBuilder
                stringBuilder.setLength(0);
                stringBuilder.append(substring);
                stringBuilder.append("已审核完成;");
            }
        }
        if (CollectionUtil.isNotEmpty(unCancelingOrders)) {
            unCancelingOrders.forEach(order -> {
                // 可能多个物流对应一个订单 收集全部物流号
                List<OrderParcel> equalsLists = orderParcels.stream().filter(orderParcel -> orderParcel.getOrderId().equals(order.getId())).collect(Collectors.toList());
                String collect = equalsLists.stream().map(OrderParcel::getTrackingNumber).collect(Collectors.joining(","));
                stringBuilder.append(collect);
                stringBuilder.append("对应的订单号:[");
                stringBuilder.append(order.getOrderNo());
                stringBuilder.append("],");
                // 添加换行符，方便查看每个订单的信息
                stringBuilder.append("\n");
            });
            if (StrUtil.isNotBlank(stringBuilder)) {
                String substring = stringBuilder.substring(0, stringBuilder.length() - 1);
                // 清空 StringBuilder
                stringBuilder.setLength(0);
                stringBuilder.append(substring);
                stringBuilder.append("还未提交审核;");
            }
        }
        String notExitTNOStr = String.join(",", notExitTNOs);
        if (StrUtil.isNotBlank(notExitTNOStr)) {
            stringBuilder.append("物流号[");
            stringBuilder.append(notExitTNOStr);
            stringBuilder.append("]不存在;");
        }
        return CommonResult.success(stringBuilder.toString());
    }

    @Override
    public CommonResult<CommonPage<UNRefundedOrderPageVO>> pageUNRefundedOrder(UNRefundedOrderPageRequest request) {
        List<UmsAdmin> users = adminService.lambdaQuery().like(UmsAdmin::getEmail, request.getEmail()).select(UmsAdmin::getId).list();
        Page<Order> orderPage = Optional.ofNullable(
                orderService.page(
                        new Page<>(request.getPageNum(), request.getPageSize()),
                        Wrappers.<Order>lambdaQuery()
                                .in(CollectionUtil.isNotEmpty(users), Order::getUserId, users.stream().map(UmsAdmin::getId).collect(Collectors.toSet()))
                                .ne(Order::getStatus, OrderStatus.DRAFT.getValue())
                                .isNull(Order::getEarnestTime)
                                .gt(Order::getEarnest, 0)
                                .select(Order::getId, Order::getOrderNo, Order::getEarnest, Order::getStatus,
                                        Order::getUserId, Order::getCreateTime, Order::getCreatedAt)
                                .orderByDesc(Order::getCreatedAt))
        ).orElse(new Page<Order>());
        return CommonResult.success(CommonPage.restPage(
                new Page<UNRefundedOrderPageVO>()
                        .setCurrent(orderPage.getCurrent())
                        .setSize(orderPage.getSize())
                        .setTotal(orderPage.getTotal())
                        .setRecords(
                                Optional.ofNullable(orderPage.getRecords()).orElse(Lists.newArrayList()).stream().map(order -> {
                                    UNRefundedOrderPageVO pageVO = new UNRefundedOrderPageVO();
                                    BeanUtils.copyProperties(order, pageVO);
                                    return pageVO;
                                }).collect(Collectors.toList()))));
    }

    @Override
    public void mock(List<Integer>    summaryUserId, String startDay, String endDay)  {
        log.info("==================JOB触发预上网回传开始=============");

        //查db
        List<UserOrderSummaryVO> oneWeekAgoSummaryNew = orderService.countGroupByDate(startDay, endDay, summaryUserId);

        Map<Integer, List<UserOrderSummaryVO>> groupedByUserId = oneWeekAgoSummaryNew.stream()
                .collect(Collectors.groupingBy(UserOrderSummaryVO::getUserId));


        groupedByUserId.forEach((userId, userOrderSummaryList) -> {
            log.info("User ID: " + userId);

            for (UserOrderSummaryVO userOrderSummaryVO : userOrderSummaryList) {
                String orderDate = userOrderSummaryVO.getOrderDate();
                //按人按天查待运输的订单号
                LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
                //查订单id 订单号和平台号
                queryWrapper.select(Order::getId
                );
                //指定先更新某着急的客户的
                queryWrapper.eq(userId != null, Order::getUserId, userId);
                queryWrapper.eq(Order::getStatus, OrderStatus.RECENT);
                //当天
                queryWrapper.lt(Order::getCreateTime, orderDate + " 23:59:59");
                queryWrapper.gt(Order::getCreateTime, orderDate + " 00:00:00");

                List<Order> list = orderService.list(queryWrapper);
                List<Integer> orderIdNoInfo = list.stream().map(Order::getId)
                        .collect(Collectors.toList());
                List<OrderParcel> parcelByOrderIdList = orderParcelService.getParcelByOrderIdList(orderIdNoInfo);
                List<String> trackingNumbers = parcelByOrderIdList.stream().map(OrderParcel::getTrackingNumber).collect(Collectors.toList());
                //模拟去查，查了后track17才会回传
                qucha1(trackingNumbers);

            }


        });


        log.info("==================JOB触发预上网回传结束=============");


    }


}
